float uses 32 bits and long uses 64 bits. Why is this allowed by the compiler then?
float x = 5555555555555555555L;
The range of float
is broader than the range of long
. So while you can certainly lose precision with an assignment like this (and can when assigning a long
value to double
too), the general magnitude is already representable - so there's never be a need to throw an exception due to it being out of range, for example.
The JLS (section 5.1.2) says this:
A widening primitive conversion from
int
tofloat
, or fromlong
tofloat
, or fromlong
todouble
, 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).