Every time I think I understand about casting and conversions, I find another strange behavior.
long l = 123456789L; float f = l; System.out.println(f); // outputs 1.23456792E8
Given that a long
has greater bit-depth than a float
, I would expect that an explicit cast would be required in order for this to compile. And not surprisingly, we see that we have lost precision in the result.
Why is a cast not required here?
Long class has the following methods for converting long type value to other primitive types. byte byteValue() returns the value of this Long as a byte. double doubleValue() returns the value of this Long as a double. float floatValue() returns the value of this Long as a float.
From float to long you could lose all behind the floating point so there will be no implicit cast because normally you do not want to lose this information. You may well lose information going from long to float . That's the point of the question.
Casting between primitive types enables you to convert the value of one type to another primitive type is called Primitive Type Casting. This is most commonly occurs with the numeric data types . But boolean primitive type can never be used in a cast.
Types of Casting in Java Two types of casting are possible in Java are as follows: Implicit type casting (also known as automatic type conversion)
The same question could be asked of long
to double
- both conversions may lose information.
Section 5.1.2 of the Java Language Specification says:
Widening primitive conversions do not lose information about the overall magnitude of a numeric value. Indeed, conversions widening from an integral type to another integral type do not lose any information at all; the numeric value is preserved exactly. Conversions widening from float to double in strictfp expressions also preserve the numeric value exactly; however, such conversions that are not strictfp may lose information about the overall magnitude of the converted value.
Conversion of an int or a long value to float, or of a long value 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).
In other words even though you may lose information, you know that the value will still be in the overall range of the target type.
The choice could certainly have been made to require all implicit conversions to lose no information at all - so int
and long
to float
would have been explicit and long
to double
would have been explicit. (int
to double
is okay; a double
has enough precision to accurately represent all int
values.)
In some cases that would have been useful - in some cases not. Language design is about compromise; you can't win 'em all. I'm not sure what decision I'd have made...
The Java Language Specification, Chapter 5: Conversion and Promotion addresses this issue:
5.1.2 Widening Primitive Conversion
The following 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
Widening primitive conversions do not lose information about the overall magnitude of a numeric value.
...
Conversion of an int or a long value to float, or of a long value 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
To put it another way, the JLS distinguishes between a loss of magnitude and a loss of precision.
int
to byte
for example is a (potential) loss of magnitude because you can't store 500 in a byte
.
long
to float
is a potential loss of precision but not magnitude because the value range for floats is larger than that for longs.
So the rule is:
Subtle? Sure. But I hope that clears that up.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With