I haven't tried this with the latest/greatest gcc [perhaps someone could please?] but I was disappointed that with gcc 4.0.2 this code ['essence' only supplied] produced a rather dumb result [IMHO] …
#include <stdio.h>
#include <math.h>
int main(void)
{
long n = 42;
printf("%lf\t%ld\n", pow(n, 2), (long)pow(n, 2));
return 0;
}
Output with gcc version 4.0.2
1764.000000 1763 // <- hmmmm!
You'd [possibly] have thought that gcc's pow() might do the right thing with integral/discrete values – well – I would.
Interestingly, MS's VC6 does do the right thing …
Output with Visual C++ v6
1764.000000 1764
So, the gcc 'fix' is to do something like:
(long)ceil(pow(n, 2)) - and that's just ugly!
Of course, as this is just n ^ 2, it could here be n * n here, but that's off the point I think I'm trying to make – imagine, say, using a few other values … here's 1 to 5
Compiled gcc code output
1.000000 1
4.000000 4
9.000000 9
16.000000 16
25.000000 24 // <- hmmmm!
Compiled VC6 code output:
1.000000 1
4.000000 4
9.000000 9
16.000000 16
25.000000 25
Ok, so, you might spot something wrong here IF you happened to see/use this value before you used it as part of a further calculation. Or, your inputs might be small enough that you 'spot' something wrong with the result.
But, say these values are somewhat bigger … here's another five outputs from the gcc code [without the comparison – would spot that there's an occasional 'off by one' here]:
3980025.000000 3980024 // <- hmmmm!
3984016.000000 3984016
3988009.000000 3988008 // <- hmmmm!
3992004.000000 3992004
3996001.000000 3996000 // <- hmmmm!
And here they are from VC6:
3980025.000000 3980025
3984016.000000 3984016
3988009.000000 3988009
3992004.000000 3992004
3996001.000000 3996001
Of course, it seems as though gcc's implementation is calculating the result of 42 ^ 2 as something like 1763.9999999999, but you know, I can't really find it in my heart to forgive it doing this with integral values somehow!