Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to get floating point error in this case?

I know that float arithmetic is tricky, but I am not sure if it is possible to get a mistake if you have a division followed by the inverse multiplication. Written in code, is it possible, that this method will return false:

public boolean calculate(float a, float b) {
        float c = a / b;
        return (a == (c * b));
}
like image 513
Ivaylo Toskov Avatar asked Dec 28 '14 20:12

Ivaylo Toskov


2 Answers

Simple answer is - yes. This example definitely returns false:

public boolean alwaysFalse(){
        float a=Float.MIN_VALUE;
        float b=Float.MAX_VALUE;
        float c = a / b;
        return a == c * b;
}

Updated
More general answer is that there are two cases when false happens in your method:
1) when significand if overflowed (i.e. division evaluates to more digits than significand can hold)
2) after exponent gets to its minimum so you can't divide further without loosing least significant bits of significand

You may construct examples for 'a' that guarantee false - like when significand's most and least significant bits are 1 (binary): 10000...000001e10 etc

like image 81
sberezin Avatar answered Oct 29 '22 21:10

sberezin


you can simply check for such cases on your own. For example with this code:

public class Main {


    public static void main(String[] args) {
        for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {
            for (int j = Integer.MIN_VALUE; j < Integer.MAX_VALUE; j++) {
                if (!calculate(i, j))
                    System.out.println(i + " " + j);
            }
        }

    }

    public static boolean calculate(float a, float b) {
        float c = a / b;

        return (a == (c * b));
    }
}

this returns many cases like:

1 - 6957633
1 - 6957635
1 - 6957644

like image 44
lwi Avatar answered Oct 29 '22 20:10

lwi