user3631106
user3631106

Reputation: 1

Float to long typecasting issue in java

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

Answers (2)

Matt
Matt

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

Valette_Renoux
Valette_Renoux

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

Related Questions