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));
}
Ivaylo Toskov
  • 3,911
  • 3
  • 32
  • 48

3 Answers3

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

sberezin
  • 3,266
  • 23
  • 28
  • Thanks for you answer. Are there any examples with values, which are not extreme (Infinities, min/max values, NaNs or zeroes), just simple numbers? – Ivaylo Toskov Dec 28 '14 at 20:42
  • @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. – Maroun Dec 28 '14 at 20:46
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

lwi
  • 1,682
  • 12
  • 21
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.

Maroun
  • 94,125
  • 30
  • 188
  • 241