私はフロートでスキャンしようとしています:13.8518009935297。 最初のルーチンは私のもので、2番目はMacOSX libcの strtod、3番目のものはGMPのmpf_get_d()で、 perls numeric.c:Perl_my_atof2()です。 4つの機能のためにPerlの仮数は他の倍数と異なります
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);
戻り値は次のとおり:最初の三つの機能の差が丸めさ
my-func : 0xbb41f 0x4283d21b
strtod : 0xbb41f 0x4283d21c
GMP : 0xbb41f 0x4283d21b
perl : 0xbb41f 0x4283d232
私は仮数を印刷するために、このスニペットを使用します。 しかし、perlの仮数は全く同期していません。
文字列に4つの倍精度文字をすべて再度印刷すると、同じ小数点以下2桁も戻ってくるので、数字は等しいようです。
私の質問: my-func、strtod、GMPの違いは四捨五入です。しかし、 なぜperlの仮数はあまり同期していませんが、それでもなお が10進数に変換された場合、それは再び同じ数値として終了します。 違いは22なので、小数点以下は です。これをどうすれば説明できますか?
追加: 申し訳ありませんが、私は問題を考え出したと思う:
$r = rand(25);
$t = $p->tokenize_str("$r");
tokenize_str()が倍増する文字列からの変換の私の実装でした。 しかし、perl stringify "$ r"は$ rを13.8518009935297として出力します。これはすでに の切り捨てです。 $ rの実際の値は異なっているので、最後に $ tと$ rのバイナリを分岐させた値が得られます。ここで
[このページ](http://babbage.cs.qc.cuny.edu/IEEE-754.old/64bit.html)によれば、その仮数は実際に表示するよりも2桁多い10進精度を持っています: '13.851800993529700 '。 Perlのバージョンは '13.851800993529740'です。だから違いはあなたの精度のレベルでは重要ではありません。それでも、なぜPerlが異なるのかは興味深い質問です。 –
申し訳ありませんが、エラーを見つけました(上記参照)。とにかく答えをありがとう... –