Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to compare a float and an int in Java?

Is it safe to compare a float and an integer like this?

private static void foo(float n) {
    if (n >= 1 || n <= 0) {
      // code 
    } 
}

According to the JLS (5.6.2. Binary Numeric Promotion) if one of the parameters is float, the other is converted to float before comparison. But as far as I understand, such a comparison will return true if the converted float is binary identical to the original float. How can we ensure it?

like image 236
Maksim Dmitriev Avatar asked Jan 04 '23 18:01

Maksim Dmitriev


1 Answers

Yes, your specific example is fine, since both 0 and 1 can be exactly represented as a float.

Note that this is not true in general: there are many large int values that's can't be represented exactly as a float. For example, the following prints out true (Ideone) even though 2_000_000_001 does not equal 2_000_000_000:

import java.util.*;
import java.lang.*;
import java.io.*;

class FloatTest {

    private static boolean isTwoBillion(float f) {
        return f == 2_000_000_000;
    }

    public static void main (String[] args) {
        System.out.println(isTwoBillion(2_000_000_001));
    }

}

Note that, unlike float, double has wide enough mantissa to store every 32-bit int value.

However, there are long values that cannot be represented as doubles. This starts occurring at long value 9_223_372_036_854_764 which is Long.MAX_VALUE/1000 - 10. The number one greater (...765) has no double counterpart, while the following number (...766) does. Put another way, starting with ...764 as a double, incrementing the last bit of the mantissa gives ...766 when converted back to long.

like image 95
NPE Avatar answered Jan 15 '23 12:01

NPE