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

3

5

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));
}
Stenotype answered 28/12, 2014 at 20:29 Comment(0)
O
4

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

Overflow answered 28/12, 2014 at 20:38 Comment(2)
Thanks for you answer. Are there any examples with values, which are not extreme (Infinities, min/max values, NaNs or zeroes), just simple numbers?Stenotype
@IvayloToskov Just numbers, as if you're worried about 1/3 for example, c won't be accurate, but if you multiply it by 3, it will be rounded again to 1.Extensible
A
3

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

Arcanum answered 28/12, 2014 at 20:44 Comment(3)
Include 0 to the loops to get more edge cases; don't worry, it's allowed.Extensible
You are right, I updated it to do a complete bruteforce search.Arcanum
Thank you for your answer! An explanation will be highly valued, because I can't really understand why exactly these values cause this behavior.Stenotype
E
0

Yes.

calculate(0,0)

returns false because c will have the value NaN, so c * b will also be NaN, but a is 0, which is not equal to NaN.

Extensible answered 28/12, 2014 at 20:33 Comment(4)
I ignored this scenario and you are entirely correct, but I was interested in cases, where flaws in floating point precision are being exploited.Stenotype
@IvayloToskov In this case you're safe, it'll always be true.Extensible
Would it be possible for values other than 0?Unmoor
@Unmoor Any (X, 0) pair.Extensible

© 2022 - 2024 — McMap. All rights reserved.