Legacy code I am to maintain has a function with a variable x of type double. This variable contains a position measured in meters. It is expected to hold a value in the mm range, let's say 0.0001 < x < 0.01.
Then I noticed a comment in the code like this:
// We will take the 6th power of this variable.
// Convert number to mm to get better accuracy.
x /= 1.0e-3;
double y = pow(x, 6.0);
- Does this make sense, is the precision of pow() indeed better when the first parameter is of the order of magnitude of 1? Given the way I think floating point numbers work, I would not expect the size of the mantissa to matter, as long as one is not running into the limits.
- Should one scale down parameters considerable larger than 1 too?
- Bonus question: does the value of the second parameter (the power) influence precision? I.e. is taking higher powers less accurate than small powers?
The target platform is Linux 3.10.x for x86_64 and we use the GCC compiler version 4.9.3.
I tried a little test program and it does indeed show larger (but still not very significant) errors when using parameters that are much larger or smaller than 1, but this might also be caused by how the inputs and/or results can be represented by floating point numbers?
#include <stdio.h>
#include <math.h>
void printpow(double d)
{
double pow6 = pow(d, 6.0);
printf("% 8g ^ 6 = %.20g\n", d, pow6);
}
int main(int argc, char **argv)
{
printpow(7.0e-10);
printpow(7.0e-6);
printpow(7.0e-3);
printpow(7.0);
printpow(7.0e3);
printpow(7.0e6);
printpow(7.0e10);
return 0;
}
Gives as output:
7e-10 ^ 6 = 1.1764899999999995812e-55
7e-06 ^ 6 = 1.1764899999999999629e-31
0.007 ^ 6 = 1.1764900000000001195e-13
7 ^ 6 = 117649
7000 ^ 6 = 1.1764900000000000603e+23
7e+06 ^ 6 = 1.1764899999999999889e+41
7e+10 ^ 6 = 1.1764900000000000914e+65