1

I'm trying to optimize a chunk of C code I'm writing and I've noticed that products are way faster than divisions. This is a well known issue and very well explained pretty everywhere.

With that optimization in mind, given that I'm dividing by the same number over and over again, I tried to compute the inverse of that number just once and then multiply by it. However, I noticed that the results were not exactly the same.

I'va managed to write a really simple example in which the differences I'm talking about are clear:

#include <stdio.h>

int main(){
    double D = 1.1891;
    double Dinv = 1./D;

    double a = 23123.1234;
    double b = 156.123871;

    printf("1/D    = %.60f\n", 1./D);
    printf("Dinv   = %.60f\n", Dinv);
    printf("1/D == Dinv? %s\n\n", 1./D == Dinv ? "True" : "False");

    printf("a/D    = %.60f\n", a/D);
    printf("a*Dinv = %.60f\n\n", a*Dinv);
    printf("a/D == a*Dinv? %s\n\n", a/D == a*Dinv ? "True" : "False");

    printf("b/D    = %.60f\n", b/D);
    printf("b*Dinv = %.60f\n\n", b*Dinv);
    printf("b/D == b*Dinv? %s\n\n", b/D == b*Dinv ? "True" : "False");
}

As you can see, I test whether a/D is equal to a*Dinv, where Dinv = 1/D, and the same test with b. The output of this code in my machine is the following:

1/D    = 0.840972163821377516335076052200747653841972351074218750000000
Dinv   = 0.840972163821377516335076052200747653841972351074218750000000
1/D == Dinv? True

a/D    = 19445.903120006725657731294631958007812500000000000000000000000000
a*Dinv = 19445.903120006729295710101723670959472656250000000000000000000000

a/D == a*Dinv? False

b/D    = 131.295829619039608360253623686730861663818359375000000000000000
b*Dinv = 131.295829619039608360253623686730861663818359375000000000000000
b/D == b*Dinv? True

As you can see in the output, the tests results are different: we can see that a/D is not equal to a*Dinv but that b/D is exactly the same as b*Dinv. This behaviour changes with the numbers tested (a and b are not numbers I'm really interested in, they are just examples I tested). My questions are:

  1. Why are a/D and a*Dinv different?
  2. Why some numbers pass the test and others don't?
  3. Can we say something about the accuracy? I mean, given a/D and a*Dinv, can we say any of them is more accurate than the other?

Thank you!

Alejandro
  • 227
  • 1
  • 12
  • If you look at the steps. `a/D` will be the most accurate. `Dinv=1/D` will give you some truncation/rounding before `a*Dinv` happens. – matt Aug 25 '16 at 13:01

1 Answers1

1

To answer the question in part, the results of a/D and a*Dinv may be different because in a*Dinv, which is a*(1.0f/D), one additional operation is involved, which potentially causes a loss of accuracy.

Codor
  • 17,447
  • 9
  • 29
  • 56