Hermit さんが書きました:
i->94906267
e->9007199515875288.000000
i * i は 9007199515875289 です。
これは、16進で 0x2000000f9097d9 ですから 54ビットの精度が必要です。
double の精度は 53ビットなので、sqrt() の引数として渡すとき
最下位のビットが落ちて 9007199515875288.0 となります。 なので、
sqrt() の結果は 94906267.0 にならず、94906266.99999999473... になる
のですが、これは内部の浮動小数点レジスタに持っている値ですから、
double の変数にストアすると、54ビット目を丸めて 53ビットにすると
94906267.0 になるのです。
sqrt() の結果を double の変数にストアせず、他の double の変数と
比較するとき、BCC は浮動小数点レジスタの値を丸めずに比較しています。
コード:
#include <stdio.h>
#include <math.h>
int main(void)
{
int i;
for (i = 94906260; i < 94906275; i++) {
__int64 j = (__int64)i * i;
long double e = sqrt((double)i * i);
printf("%d %I64d %I64x %.15Lf\n", i, j, j, e);
}
return 0;
}
実行結果
コード:
94906260 9007198187187600 1fffffc05e6d90 94906260.000000000000000
94906261 9007198377000121 1fffffcbaebcb9 94906261.000000000000000
94906262 9007198566812644 1fffffd6ff0be4 94906262.000000000000000
94906263 9007198756625169 1fffffe24f5b11 94906263.000000000000000
94906264 9007198946437696 1fffffed9faa40 94906264.000000000000000
94906265 9007199136250225 1ffffff8eff971 94906265.000000000000000
94906266 9007199326062756 200000044048a4 94906266.000000000000000
94906267 9007199515875289 2000000f9097d9 94906266.999999994730000
94906268 9007199705687824 2000001ae0e710 94906268.000000000000000
94906269 9007199895500361 20000026313649 94906268.999999994730000
94906270 9007200085312900 20000031818584 94906270.000000000000000
94906271 9007200275125441 2000003cd1d4c1 94906270.999999994730000
94906272 9007200464937984 20000048222400 94906272.000000000000000
94906273 9007200654750529 20000053727341 94906272.999999994730000
94906274 9007200844563076 2000005ec2c284 94906274.000000000000000
i = 94906266
i * i = 9007199326062756 = 0x200000044048a4
これは下位ビットが 0100 なので、精度は 52ビットであり正しい結果が出ます。
94906268, 94906270, 94906272 などの偶数も同様です。