问题
Why the following works
float f = 10l // OK 32 bits to 64 ?
float is only 32 bits and long 64 bits so there is NO room for float in the long
and this one doesn't
long l = 10f //compile error
Could someone explain to me how kind of casting works?
回答1:
The conversion from long
to float
is specifically allowed for assignment by the JLS, Section 5.1.2:
19 specific conversions on primitive types are called the widening primitive conversions:
byte to short, int, long, float, or double
short to int, long, float, or double
char to int, long, float, or double
int to long, float, or double
long to float or double
float to double
And
A widening primitive conversion from int to float, or from long to float, or from long to double, may result in loss of precision - that is, the result may lose some of the least significant bits of the value. In this case, the resulting floating-point value will be a correctly rounded version of the integer value, using IEEE 754 round-to-nearest mode (§4.2.4).
So, the range of values is covered, but there may be a loss of precision. That is allowed and expected.
The other line:
long l = 10f;
is a primitive narrowing conversion, which the JLS, Section 5.2 "Assignment Contexts", doesn't specifically allow:
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.
Note that an explicit cast would allow the narrowing primitive conversion.
long l = (long) 10f; // Compiles
回答2:
You're probably looking for documentation on widening primitive conversions, and narrowing primitive conversions.
long
to float
is a widening conversion, and float
to long
is a narrowing conversion.
In general, widening conversions are safe because what you're converting to can always take whatever value the narrower type might be dishing out. Narrowing conversions are not always safe, because you could destroy information or end up with NaN
.
回答3:
The first initialization is a widening primitive conversion.
The second initialization is a narrowing conversion. Loss of information may occur. Consider what would happen if you tried to assign long l = 10.5f
- the integral type could not represent the fractional part.
来源:https://stackoverflow.com/questions/26046571/primitive-cast-and-assignments-in-java