Reputation: 1
Example 1:
public class Test {
public static void main(String args[]){
long l1 =8589934592L;
float f1= l1;
long l2= (long)f1;
System.out.println("Input long::"+l1);
System.out.println("Float value::"+f1);
System.out.println("Typecasted value::"+l2);
}
}
Output of for first class:
Input long::8589934592
Float value::8.5899346E9
Typecasted value::8589934592
Example 2:
public class Test {
public static void main(String args[]){
long l1 =6788819226L;
float f1= l1;
long l2= (long)f1;
System.out.println("Input long::"+l1);
System.out.println("Float value::"+f1);
System.out.println("Typecasted value::"+l2);
}
}
Output of for second class:
Input long::6788819226
Float value::6.7888195E9
Typecasted value::6788819456
Typecasting is not happening properly. Both classes has different behaviours. Why example 2 has different value after type casting. Please let me know the reason?
Upvotes: 0
Views: 81
Reputation: 1484
You are getting almost same results from all of them, although they might look quite different to you if you are not used to Scientific notation of using 1E
values. Note that there is E
between numerical numbers in float representations.
In number formats, 6.7888195E9
means 6.7888195 * 10^9
, which is approximately same as 6788819226
but with less precision. In float
type, it could not give more details because your numbers were bigger than the maximum number float
type variables can store in them.
Try with smaller numbers, which float
can store all numbers without losing any precision:
long l1 =8589944L;
float f1= (float) l1;
long l2= (long)f1;
System.out.println("Input long::"+l1);
System.out.println("Float value::"+f1);
System.out.println("Typecasted value::"+l2);
You will notice that the result is:
Input long::8589944
Float value::8589944.0
Typecasted value::8589944
which does look familiar to you. This shows that the representation of float values in your examples used E
notation to show that it is a large number, which kind of indicates to you that it is potentially losing some precision. When we write math terms in exponential forms, the numbers are usually quite big and we tend to care less about small values with them.
Type float
provides less precision because float has less bits to store numbers. Having less bits means that it uses less memory but can only have limited accuracy compared to long. long
uses more bits (1s and 0s in computer memory) than float
and if you put it in a form of binary numbers long
would have more 1s
and 0s
than float
, which is why it is called long
.
In Java, long
uses 64 bits and float
uses 32 bits. More details at here.
I hope this helps you to understand what's going on.
Upvotes: 0
Reputation: 366
Float does not have enough precision to encode exactly this number. If you used double, it would work:
public class Test {
public static void main(final String args[]) {
long l1 = 6788819226L;
double f1 = l1;
long l2 = (long) f1;
System.out.println("Input long::" + l1);
System.out.println("Double value::" + f1);
System.out.println("Typecasted value::" + l2);
}
}
Output:
Input long::6788819226
Double value::6.788819226E9
Typecasted value::6788819226
You can read https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.3 to understand the exact limitations of float. To give an approximation, integer up to 2^24 will be exactly saved in float, after that it can be an approximation (or exact, depending on the number). For doubles, this goes up to 2^53.
The reason your first example works exactly is because 8589934592 is a power of 2, for which the approximation is equal to the number (if you read the specification you will understand this).
Upvotes: 1