Suppose you quickly want to determine which of ฯ or ฯ / 10 has the largest relative error if it is presented in IEEE 754 binary format. In addition, you only have the C compiler.
You can write a C program below or a more compact version:
#include <stdio.h> #include <math.h> volatile long double pil = 3.14159265358979323846L; volatile double pi = 3.14159265358979323846; volatile long double tpil = 0.314159265358979323846L; volatile double tpi = 0.314159265358979323846; int main() { volatile long double abs = pil - pi; printf("%La\n%La\n%La\n", pil, (long double)pi, abs); printf("pi: abs err %La -> rel %La\n", abs, abs / pil); volatile long double abst = tpil - tpi; printf("pi/10: abs err %La -> rel %La\n", abst, abst / tpil); }
The funny thing is that this program shows that the relative errors ฯ and ฯ / 10 are identical:
0xc.90fdaa22168c235p-2
0xc.90fdaa22168cp-2
0x8.d4p-56
pi: abs err 0x8.d4p-56 -> rel 0xb.3d85789395e215bp-58
pi / 10: abs err 0xe.2p-60 -> rel 0xb.3d85789395e215bp-58
I added volatile qualifiers and intermediate calculations to look at the generated assembly and make sure that this is not a compiler error. This is apparently not the case.
This is strange because many other values โโof v do not have the property that the relative error v coincides with the relative error v / 10. I checked with 0.1 and 0.3. Also, this is not a matter of magnitude, because 3 and 3.5 obviously have different relative errors than their corresponding tenths. Although 5, 10, 15, ... have the same relative error as their corresponding tenths, they should be considered as exceptions.
Now the program does not calculate the exact values โโof relative errors. It can contain only 12 bits (one sign bit plus 11 bits of the difference between a 64-bit value and a 53-bit value). Thus, it was possible a priori something like one case in 4096, when the absolute error ฯ was obtained as a 10-fold absolute error ฯ / 10.
This still seems an unlikely coincidence. Was there an a priori case that a real constant, taken between 3 and 3.5, had the same relative error as its tenth, if it is represented as double more than my intuition says that it should be? Or is there another way to see this, for example, "it happens as soon as the (double) (ฯ / 10) value has enough finite zeros to multiply by ten to be exact", which seems much more frequent (close to 1/8 )?