0

In floating point math, is it always true that (x / y) * y == x, if x and y are exactly representable integers?

I've tried various values of x and y and it seems like it's true, but I'm not sure. If it is true, I'd like to understand why. If it's not true, I'd like to understand for what values it's not true.

I wasn't expecting it to be true because I know that x / y in floating point isn't guaranteed to be exactly equal to x / y using real numbers, so I thought that inaccuracy would be magnified by the multiplication, leading to the calculated result being different from x.

Nick Kovac
  • 487
  • 3
  • 10
  • I'm sure I've seen this asked before. But no, it's not true, even if you restrict to the special case where `x == 1.0`. A short `for` loop in your favourite language should quickly find counterexamples. – Mark Dickinson Jan 27 '22 at 11:23
  • 1
    For example, with IEEE 754 binary64 floating-point and the default round-ties-to-even rounding mode, `1.0 / 49.0 * 49.0` does not give `1.0`. – Mark Dickinson Jan 27 '22 at 11:26
  • https://stackoverflow.com/q/68115518/270986 is pretty close to a duplicate – Mark Dickinson Jan 27 '22 at 11:27

1 Answers1

2

It's not true:

    for (var x = 1.0; x <= 30.0; x++)
        for (var y = 1.0; y <= 30.0; y++)
            if ((x / y) * y != x)
                System.out.printf("%s / %s * %2$s = %s%n", x, y, (x / y) * y);

Output:

7.0 / 25.0 * 25.0 = 7.000000000000001
13.0 / 23.0 * 23.0 = 12.999999999999998
14.0 / 25.0 * 25.0 = 14.000000000000002
15.0 / 11.0 * 11.0 = 14.999999999999998
15.0 / 13.0 * 13.0 = 14.999999999999998
15.0 / 22.0 * 22.0 = 14.999999999999998
15.0 / 26.0 * 26.0 = 14.999999999999998
15.0 / 29.0 * 29.0 = 15.000000000000002
21.0 / 19.0 * 19.0 = 21.000000000000004
23.0 / 21.0 * 21.0 = 23.000000000000004
25.0 / 11.0 * 11.0 = 25.000000000000004
25.0 / 22.0 * 22.0 = 25.000000000000004
26.0 / 23.0 * 23.0 = 25.999999999999996
27.0 / 13.0 * 13.0 = 27.000000000000004
27.0 / 21.0 * 21.0 = 27.000000000000004
27.0 / 23.0 * 23.0 = 27.000000000000004
27.0 / 26.0 * 26.0 = 27.000000000000004
28.0 / 25.0 * 25.0 = 28.000000000000004
29.0 / 7.0 * 7.0 = 29.000000000000004
29.0 / 14.0 * 14.0 = 29.000000000000004
29.0 / 25.0 * 25.0 = 28.999999999999996
29.0 / 27.0 * 27.0 = 29.000000000000004
29.0 / 28.0 * 28.0 = 29.000000000000004
30.0 / 11.0 * 11.0 = 29.999999999999996
30.0 / 13.0 * 13.0 = 29.999999999999996
30.0 / 22.0 * 22.0 = 29.999999999999996
30.0 / 26.0 * 26.0 = 29.999999999999996
30.0 / 29.0 * 29.0 = 30.000000000000004

You said you found it seemed to be true; perhaps you weren't printing with sufficient precision.

k314159
  • 5,051
  • 10
  • 32