100000000(1億)の2乗は、10000000000000000(1京)。
したがって、(1京 - 1) の 9999999999999999 の平方根は 100000000より小さく、
整数平方根は 99999999 のはず。
ところが、sqrt(9999999999999999) は 100000000 になってしまいます。
なぜかというと次のコードを実行すると分かります。
C
1#include <stdio.h>
2
3int main(void)
4{
5 for (long long n = 9999999999999995; n <= 10000000000000005; n++) {
6 double d = n;
7 printf("%17lld, %llx, %.13a, %19.1f\n", n, n, d, d);
8 }
9}
実行結果
9999999999999995, 2386f26fc0fffb, 0x1.1c37937e07ffep+53, 9999999999999996.0
9999999999999996, 2386f26fc0fffc, 0x1.1c37937e07ffep+53, 9999999999999996.0
9999999999999997, 2386f26fc0fffd, 0x1.1c37937e07ffep+53, 9999999999999996.0
9999999999999998, 2386f26fc0fffe, 0x1.1c37937e07fffp+53, 9999999999999998.0
9999999999999999, 2386f26fc0ffff, 0x1.1c37937e08000p+53, 10000000000000000.0
10000000000000000, 2386f26fc10000, 0x1.1c37937e08000p+53, 10000000000000000.0
10000000000000001, 2386f26fc10001, 0x1.1c37937e08000p+53, 10000000000000000.0
10000000000000002, 2386f26fc10002, 0x1.1c37937e08001p+53, 10000000000000002.0
10000000000000003, 2386f26fc10003, 0x1.1c37937e08002p+53, 10000000000000004.0
10000000000000004, 2386f26fc10004, 0x1.1c37937e08002p+53, 10000000000000004.0
10000000000000005, 2386f26fc10005, 0x1.1c37937e08002p+53, 10000000000000004.0
long long は 63ビットの精度があります。10000000000000000 は 54ビットです。
double は 53ビットの精度しかありません。
9999999999999999~10000000000000001 の 3つの値が 10000000000000000.0 という
一つの値になってしまいます。
9999999999999999の平方根を double の sqrt で求められないのはこのためです。