Java int += double syntax surprise [duplicate] - java

This question already has answers here:
Varying behavior for possible loss of precision
(1 answer)
Why does Java perform implicit type conversion from double to integer when using the "plus equals" operator? [duplicate]
(2 answers)
Why don't Java's +=, -=, *=, /= compound assignment operators require casting?
(11 answers)
Closed 9 years ago.
I have run into the following surprising line:
int x = 7;
x += 0.5;
is apparently legal syntax! After the addition, x is still 7, so the double is being cast to an int and rounded down to 0, but this is done without any explicit cast in the code. Is anyone else surprised by this? What's the rationale here?
edit to clarify my question: Can anyone give a good reason for this decision? It strikes me as a terrible decision to require explicit casting everywhere else, but have this one spot in the language where you silently throw away data. Am I missing something?

x += 0.5;
is equivalent to:
x = (int) (x + 0.5)
In general:
x += y is equivalent to x = (type of x) (x + y)
See 15.26.2. Compound Assignment Operators

x += 0.5; is the same as x = (int) (x + 0.5);.

This is because compound assignment operators puts an implicit cast (automatic cast):
So
x+=0.5 => x =(int)(x + 0.5) => x = (int)(7.5) => x = 7

Related

What does * in front of = mean? [duplicate]

This question already has answers here:
Meaning of *= in Java
(4 answers)
Closed 4 years ago.
Hello everyone I have a very simple question that I just don't understand. I've tried googling it but haven't found a clear answer.
What is x after the following statements?
int x = 2;
int y = 1;
x *= y + 1;
I know that the answer is 4 but I don't understand why it is 4. Just need some clarity on what x* means exactly. Thanks!
I think this line is the one why you ask
x *= y + 1;
This is a shorthand for
x = x * (y + 1);
This works also with other operators like - and +, when the first variable is the same as the variable on the left side (which will be assigned).
Of course x is 4, if you don't understand the last statement, you can read it like this
x = x * y + 2
The x*= symbol means x=x* the result of whatever you put after the equals symbol.
x*= y+1 will turn to x = x * (y+1). The expresion you put after equals is evaluated first and then multiplied with x. The result will be cast to the type of the assignment variable (x).

Java Operator Precedence issue for a simple equation [duplicate]

This question already has answers here:
Int division: Why is the result of 1/3 == 0?
(19 answers)
Closed 4 years ago.
I am trying to implement a simple equation in Java but keep getting the wrong answer apparently due to operator precedence which I am unable to understand.
The equation is:
NewMean = ((N-1) / N) * OldMean + (Xn / N)
in a simple example:
N = 6 ; OldMean = 6 ; Xn = 16
So,
NewMean = 5/6 * 6 + 16/6 = 7.6667 (Correct answer)
but in code implementation on Java i get wrong answer (2.6665):
double NewMean = ((N-1)/N)*oldMean + (Xn/N);
If the N variable is type int, then ((N-1) / N) is computed using integer division and will round 5/6 down to 0. Change N to a floating-point type and you should get the correct answer.

Why i don't get an error? [duplicate]

This question already has answers here:
Why don't Java's +=, -=, *=, /= compound assignment operators require casting?
(11 answers)
Closed 5 years ago.
In Java if I do the following I get an error
byte b = 50;
b = b * 2; // Error! Cannot assign an int to a byte!
Ok I understood why I got that error .
But now if I do b*=2 I don't get any error. Why?
Because when you make b *= 2; in fact this operation *= will cast your int to byte.
The reason is simply because there are different rules for narrowing conversions for = and *=.
See here for details on widening in general; and then you go here to understand the difference for those *= operations.
You, see
b *= 2
works out as
b = (byte) ( (b) * 2 )
and that narrowing conversion doesn't play a role here.

Multiplying a number without using * operator [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
I was going through a programming class and was asked this tricky question which was left unanswered till the end of the class.
Question:
How can I multiply any input(Float,int etc) by 7,
without using the * operator
in TWO steps.
If anyone can give me the answer for this question with the explanation , that would be very helpful.
With TWO STEPS I mean suppose you are running a loop (i=0;i<7;i++) in
that case number of steps will be >2, also TYPE CONVERSION,
DIVISION,ADDITION etc ( Counts for steps ).
Assuming float x or double x is defined in the scope. Then I see the following possibilities to multiply it by 7 without using the * operator:
In C++, you can use the standard functors (first step: create functor, second step: call functor):
x = std::multiplies<float>()(x, 7.0f); // if x is a float
x = std::multiplies<double>()(x, 7.0); // if x is a double
Or only use division (Since the compiler already evaluates 1.0 / 7.0, this is only one step):
x = x / (1.0f / 7.0f); // if x is a float
x = x / (1.0 / 7.0); // if x is a double
Or use the *= operator (technically, it's not the * operator, but it's only one single step):
x *= 7.0f; // if x is a float
x *= 7.0; // if x is a double
Or use addition in the logarithmic scale (this is not to be taken very serious, as well as this requires more than two "steps"):
x = exp(log(x) + log(7.0));
Another option is to use an assembly instruction, but I don't want to write that now, since it's overly complicated.
If x is an integer, bit shifting is another option, but not recommended:
x = (x << 3) - x; // (x * 8) - x
You could simply use division by a seventh:
x / (1.0 / 7)
Whether this counts as "two steps" is entirely up to your definition.
add it
//initialise s as the number to be multiplied
sum=0
for(i=0;i<7;i++)
sum+=s
In C, the following hack should work for floats stored in IEEE single precision floating point format:
#include <stdint.h>
float mul7 (float x) {
union {
float f;
uint32_t i;
} u;
u.f = x;
u.i += (3 << 23); /* increment exponent by 3 <=> multiply by 8 */
return u.f - x; /* 8*x - x == 7*x */
}
That's two steps (one integer addition, one float subtraction), sort of, depending on what you count as a step. Given that C++ is more or less backwards-compatible with C, I believe a similar trick should be possible there too.
Note, however, that this hack generally won't give correct results for subnormal, infinite or NaN inputs, nor for inputs so large in magnitude that multiplying them by 8 would overflow.
Adjusting the code to use doubles instead of float is left as an exercise for the reader. (Hint: the magic number is 52.)
You may also do the following for integers:
( x<< 3) - x
// String num = "10";
// int num = 10;
float num = 10;
BigDecimal bigD = new BigDecimal(num);
BigDecimal seven = new BigDecimal(7);
System.out.println(seven.multiply(bigD));
You could use the BigDecimal & its multiply method. Works for pretty much everything.
Define "two steps"...
float result = 0.0f;
float input = 3.14f;
int times = 7;
// steps
while (times--)
result += input;
Edit: dividing by (1 / 7) won't work with int type. Also in some languages for it to work with float type, you'd have to mark them as floats:
result = input / (1.0f / 7.0f);
Add 7 by x times.
for(int i=0; i<10; i++)
result = result+7;

Java breaks strong typing! Who can explain it? [duplicate]

This question already has an answer here:
Closed 11 years ago.
Possible Duplicate:
Varying behavior for possible loss of precision
I found an inconsistence in Java strong typing check at compile time.
Please look at the following code:
int sum = 0;
sum = 1; //is is OK
sum = 0.56786; //compile error because of precision loss, and strong typing
sum = sum + 2; //it is OK
sum += 2; //it is OK
sum = sum + 0.56787; //compile error again because of automatic conversion into double, and possible precision loss
sum += 0.56787; //this line is does the same thing as the previous line, but it does not give us a compile error, and javac does not complain about precision loss etc.
Can anyone explain it to me? Is it a known bug, or desired behavior?
C++ gives a warning, C# gives a compile error.
Does Java breaks strong typing?
You can replace += with -= or *= - everything is acceptable by a compiler.
This behaviour is defined by the language (and is therefore OK). From the JLS:
15.26.2 Compound Assignment Operators
A compound assignment expression of the form E1 op= E2 is equivalent
to E1 = (T)((E1) op (E2)), where T is the type of E1, except that E1
is evaluated only once. For example, the following code is correct:
short x = 3;
x += 4.6;
and results in x having the value 7 because it is equivalent to:
short x = 3;
x = (short)(x + 4.6);
It compiles because the compiler is converting
sum += 0.56787;
to
sum = (int)(sum + 0.56787);
This has nothing to do with strong typing but only with different rules for implicit conversions.
You are looking at two different operators here. In the first case, you have the simple assignment operator "=" which does not allow assigning a double to an int. In the second case, you have the compound assignment operator "+=" which allows adding a double to an int by converting the double to an int first.

Categories