Reputation: 1774
The following declaration gives me a compile-time error "Error:(19, 13) java: incompatible types: possible lossy conversion from double to int"
int i1 = 10.0;
// Error:(19, 14) java: incompatible types: possible lossy conversion from double to int
Question 1
I understand the error but can the compiler not infer - in this particular case - that there will be no loss of precision?
Question 2
If I explicitly convert the double to an int
then it compiles fine (not even a warning) even though I am definitely losing precision in this example
int i2 = (int)9999999999999.999999999;
If I can't compile the first case - where no loss occurs - then why does this second example with the explicit conversion not even generate a compiler warning?
Upvotes: 3
Views: 386
Reputation: 159086
The assignment of a double
value to an int
variable would require a narrowing conversion, even if the value is a compile-time constant, and hence requires an explicit cast.
Except that an int
(or short
or char
) constant value can be assigned to a byte
, short
, or char
variable without casting, if the constant actually fits in the variables value range, as explicitly documented in the Java Language Specification, section 5.2. Assignment Contexts:
Assignment contexts allow the value of an expression to be assigned (§15.26) to a variable; the type of the expression must be converted to the type of the variable.
Assignment contexts allow the use of one of the following:
an identity conversion (§5.1.1)
a widening primitive conversion (§5.1.2)
a widening reference conversion (§5.1.5)
a boxing conversion (§5.1.7) optionally followed by a widening reference conversion
an unboxing conversion (§5.1.8) optionally followed by a widening primitive conversion.
If, after the conversions listed above have been applied, the resulting type is a raw type (§4.8), an unchecked conversion (§5.1.9) may then be applied.
In addition, if the expression is a constant expression (§15.28) of type
byte
,short
,char
, orint
:
A narrowing primitive conversion may be used if the type of the variable is
byte
,short
, orchar
, and the value of the constant expression is representable in the type of the variable.A narrowing primitive conversion followed by a boxing conversion may be used if the type of the variable is:
Byte
and the value of the constant expression is representable in the typebyte
.
Short
and the value of the constant expression is representable in the typeshort
.
Character
and the value of the constant expression is representable in the typechar
.
Upvotes: 2
Reputation: 120848
Interesting question
In theory this could be possible, well javac
does not complain when doing:
short s = 12;
Even if 12
here is a compile time constant of type int
, so it can deduce that no precision is lost. I guess this is what the compiler team thought would be most appropriate.
Well when you cast
is a different story, it's like saying "trust me, I know what I'm doing", even if you loose precision.
Upvotes: 1
Reputation: 271040
Answer to question 1
There is a loss of precision according to the compiler, because the compiler only sees that you have an int variable on the left and a double value on the right. The compiler is not so smart as to figure out that 10.0
will not lose precision when converted to an int.
The compiler could in theory be built to allow that statement to compile, but there is no real benefit in doing so. Almost no one writes int x = 10.0
.
Answer to question 2
Indeed, there is a loss of precision, but why did the compiler not complain? Because you used a cast. You wrote (int)
. This is you showing the compiler that you know what you're doing. By writing a cast, you are telling it that you are aware that there is a possible loss of precision.
Upvotes: 1
Reputation: 311163
In theory, a compiler could infer that the specific example in #1 wouldn't actually loose precision based on the literal's value, but as you've seen - it doesn't.
The explicit cast signals to the compiler that you are aware of the situation an handling it, so the code actually compiles. Most IDEs, however, could be configured to emit a warning in such a situation too.
Upvotes: 2