[英]Strange result using long double in C++
在 C++ 中使用 long double 算术,数字50,000,056,019,485.52605438232421875 的平方产生2,500,005,601,951,690,788,240,883,712 。 同时,数字50,000,056,019,485.526050567626953125 (与第一个数字相差不到 0.001)的平方产生2,500,005,601,951,690,787,704,01 , 2,500,005,601,951,690,787,804,01的平方。 突出显示差异:
50,000,056,019,485.52605 4382324218750 ^ 2 = 2,500,005,601,951,690,78 8240883712 50,000,056,019,485.52605 0567626953125 ^ 2 = 2,500,005,601,951,690,78 7704012800
我的机器中的 Long double 范围从 ~1e-300 到 ~1e+300。 我完全理解无法表示范围内的所有数字,但我没想到会有如此大的差异。 有人可以对此有所了解吗?
数学
鉴于d
为一个很小的值相比, a
(a+d)*(a+d) - (a)*(a)
的预期差异约为2*a*d
。
这里a
大约是 50,000,056,000,000.0, d
大约是 0.00000381……而2*a*d
大约是 381,000,000.0。 这是使用long double
所见差异的long double
:536,870,912.0。
“没想到差别这么大。” 仅“关闭”小于 2 倍。鉴于正方形代表四舍五入的产品,此处看到的正方形的差异是合理的。
一些细节:
long double
给定以下和long double
作为 10 字节, a
和b
是连续的long double
值。 它们相差 1 ULP或大约 2 64 分之一。 两个十进制代码常量都精确地保存为a, b
。
long double b = 50000056019485.526054382324218750L; // 0x1.6bcc5c9f50ec355cp+45
long double a = 50000056019485.526050567626953125L; // 0x1.6bcc5c9f50ec355ap+45
// difference
long double d = 0.000003814697265625L; // 0x0.0000000000000002p+45
a, b
的平方不能用long double
表示。 相反,报告的平方是四舍五入的值。 它们相差 2 ULP。
long double bb = 2500005601951690788240883712.0L; // 0x1.027e98e7c774ede8cp+91
long double aa = 2500005601951690787704012800.0L; // 0x1.027e98e7c774ede88p+91
// difference 536870912.0 .... 0x0.00000000000000004p+91
当乘以 2 个浮点数时,乘积中的误差预计在 +/-0.5 ULP 以内。 这里的 ULP 是 5,368,70,912,实际上平方在 0.5* 以内是正确的
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.