Pregunta

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.

¿Fue útil?

Solución

Here is some perl code to answer your question:

perl -le '($frac1, $frach)=unpack("II", pack "d", .0+"13.8518009935297");
print sprintf("%d %d 0x%03x 0x%04x", ($frach >> 31)&1, ($frach>>20)&0x5ff, $frach & 0xfffff, $frac1)'

-> 0 1026 0xbb41f 0x4283d21c

Perl gives the same result as strtod. The difference was the mistake you indicated in append.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top