I'm trying to scan in a float: 13.8518009935297 . The first routine is my own, the second is MacOSX libc's strtod, the third is GMP's mpf_get_d() the forth is perls numeric.c:Perl_my_atof2().
I use this snippet to print the mantissa:
union ieee_double {
struct {
uint32_t fracl;
uint32_t frach:20;
uint32_t exp:11;
uint32_t sign:1;
} s;
double d;
uint64_t l;
};
union ieee_double l0;
l0.d = ....
printf("... 0x%x 0x%x\n", l0.s.frach, l0.s.fracl);
The return values for the four functions are:
my-func : 0xbb41f 0x4283d21b
strtod : 0xbb41f 0x4283d21c
GMP : 0xbb41f 0x4283d21b
perl : 0xbb41f 0x4283d232
The difference between the first three functions is rounding. However perl's mantissa is quite out of sync.
If I print all four doubles to a string again I get the same decimal double back, the numbers seem to be equal.
My question: The difference between my-func, strtod, GMP is rounding. However, why is perl's mantissa so much out of sync, but still, if converted back to decimal, it ends up as the same number again. The difference is 22, so it should be noted in a decimal fraction. How can I explain this?
Append: Sorry, I think I figured out the problem:
$r = rand(25);
$t = $p->tokenize_str("$r");
tokenize_str() was my implementation of a conversion from string to double. However the perl stringify "$r" prints out $r as 13.8518009935297, which is a already truncation. The actual value of $r is different, so when I at the end the binaries of $t with $r I get values that diverge.