16

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.

Community
  • 1
  • 1
Michael P
  • 670
  • 7
  • 23
  • weird is that you are storing float in int variable – Karel Frajták Oct 21 '11 at 08:49
  • 3
    @KarelFrajtak A decimal number without a modifier (like `d` or `f`) is a double, not a float. Besides, I think you might be missing the point.. – nfechner Oct 21 '11 at 08:57
  • 1
    Java clearly made a mistake here. They should have been more precise in when the silent cast is allowed. And the reason for the cast roots in another bad decision. The spec on integeral type operations is a stinky mess. – irreputable Oct 21 '11 at 10:41
  • @irreputable: The rules for floating-point types are worse. If both were allowed, which would be more worthy of a warning: `float f=1.0/10.0;` or `double d=1.0f/10.0f;`? A good language should be able to define an `==` operator so it behaves as an equivalence relation in all cases which compile (the fact that `x==y` compiles and `y==z` compiles would not imply that `x==z` must compile, but if all three compile and two return true, the third should as well), but Java's fails in many regards. – supercat Feb 10 '14 at 22:22

3 Answers3

28

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);
McDowell
  • 107,573
  • 31
  • 204
  • 267
5

It compiles because the compiler is converting

sum += 0.56787;

to

sum = (int)(sum + 0.56787);
John B
  • 32,493
  • 6
  • 77
  • 98
  • 1
    Can You provide a link to a document, that explains this behavior. I thought that normal behavior is automatic conversion into a type with higher precision. – Michael P Oct 21 '11 at 08:50
  • 1
    The cast is performed after the addition, not before. See the top answer. – Karl Knechtel Oct 21 '11 at 09:14
3

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.

Ingo Kegel
  • 46,523
  • 10
  • 71
  • 102