Does anybody knows why this code prints 1000000000000000000
and not 1000000000000000001
as expected?
#include <stdio.h>
#include <math.h>
int main(void){
long long n = (pow(10,18) + 1);
printf("%lld ", n);
}
Does anybody knows why this code prints 1000000000000000000
and not 1000000000000000001
as expected?
#include <stdio.h>
#include <math.h>
int main(void){
long long n = (pow(10,18) + 1);
printf("%lld ", n);
}
pow(10, 18)
returns a floating point double
. The result of that, and adding 1, is indistinguishable in floating point space to the number you get back. For IEEE754, the closest double
to 1000000000000000001
is 1000000000000000000
, which more than likely accounts for your result.
(long long)pow(10, 18) + 1
might work (and probably will with a modern C toolset): you are still at the mercy of pow
returning the algebraically correct result, of which there is no guarantee, although it's becoming increasingly fashionable to regard a C implementation of pow
that doesn't return the best possible result when given integral arguments as defective - the days of pow(x, y)
being implemented as simply exp(y * log(x))
are surely over?
So two options really. Either hope all your target platforms are up to it, or use a mathematics library that has a power function for integral arguments, using a technique such as exponentation by squaring.