You can also use implicit widening conversion of integer types to floating-point, but not vice versa. There is
no loss of range going from integer to floating point, because the range of any floating-point type is larger
than the range of any integer.
Preserving magnitude is not the same as preserving the precision of a value. You can lose precision in some
implicit conversions. Consider, for example, assigning a long to a float. The float has 32 bits of data
and the long has 64 bits of data. A float stores fewer significant digits than a long, even though a
float stores numbers of a larger range. You can lose data in an assignment of a long to a float. Consider
the following:
long orig = 0x7effffff00000000L;
float fval = orig;
long lose = (long) fval;
System.out.println("orig = " + orig);
System.out.println("fval = " + fval);
System.out.println("lose = " + lose);
The first two statements create a long value and assign it to a float value. To show that this loses
precision, we explicitly cast fval to a long and assign it to another variable (explicit casts are covered
next). If you examine the output, you can see that the float value lost some precision: The long variable
orig that was assigned to the float variable fval has a different value from the one generated by the
explicit cast back into the long variable lose:
orig = 9151314438521880576
fval = 9.1513144E18
lose = 9151314442816847872
As a convenience, compile-time constants of integer type can be assigned to smaller integer types, without a
cast, provided the value of the constant can actually fit in the smaller type and the integer type is not long.
For example, the first two assignments are legal while the last is not:
short s1 = 27; // implicit int to short
byte b1 = 27; // implicit int to byte
short s3 = 0x1ffff; // INVALID: int value too big for short
Such a conversion, from a larger type to a smaller type, is a narrowing primitive conversion.
In all, seven different kinds of conversions might apply when an expression is evaluated:
- Widening or narrowing primitive conversions
- Widening or narrowing reference conversions
- Boxing or unboxing conversions
- String conversions
You have previously seen all of these. There are then five different contexts in which these conversions might
be applied, but only some conversions apply in any given context:
Assignment This occurs when assigning the value of an expression to a variable and can involve the
following: a widening primitive conversion; a widening reference conversion; a boxing conversion