C 在划分大型双数据时出错
这是我的密码C 在划分大型双数据时出错,c,C,这是我的密码 double max = pow(2,1000); double test = max/10; 测试结果是错误的。我想知道这是怎么发生的?2^1000会给出比双人间更大的答案 double max=pow(2,1000); 这一行导致溢出。问题是浮点数的精度。它们以二进制格式存储,特别是double只能在尾数中存储53+1位 当你把这么大的数字除以10时,它会丢失一些位,因为无法用二进制数精确地表示除法 实际上,甚至不可能精确地存储1/10,所以这里2的原始幂实际上没那么重要
double max = pow(2,1000);
double test = max/10;
测试结果是错误的。我想知道这是怎么发生的?
2^1000
会给出比双人间更大的答案
double max=pow(2,1000);
这一行导致溢出。问题是浮点数的精度。它们以二进制格式存储,特别是double只能在尾数中存储53+1位 当你把这么大的数字除以10时,它会丢失一些位,因为无法用二进制数精确地表示除法 实际上,甚至不可能精确地存储1/10,所以这里2的原始幂实际上没那么重要
编辑:关于其他答案-exponent可以以双精度存储11位,因此它可以处理2^1000。这取决于您使用的编译器。。As双精度值取决于编译器是否为32位64位。。如果2^1000超过了double的大小,那么它将溢出它可以处理
pow(2,1000)
但这是一种误导,它无法将它附近的任何数字作为单独的不同值进行远程处理;此时可表示数字之间的间隔约为53位,因此pow(21000)-pow(2946)
实际上与pow(21000)
相同。在达到100位之前,浮点会出现严重错误;在1000位,这是一个荒谬的比例上的大概数字。@ShadowRanger:pow(2100)可以绝对精确地用双精度(以及任何二进制格式)表示,因为它是2的幂。当然pow(21000)-pow(2946)
与pow(21000)
相同,因为它低于尾数精度(如我所述,指数差大于54)。但是基本上,pow(21000)/10
和1/10
之间没有区别,因为它们只在指数上不同。二者都有一个事实,即1/5不能以二进制格式精确表示。虽然标准允许使用1e37
的DBL_MAX
进行double
,但实际上每个通用系统都使用IEEE 754双精度格式,该格式有一个限制(刚好低于1.8e+308
),其中包括pow(21000)
(大致为1.0715e+301
)。对于任何使用如此大的值进行的计算,绝对误差都会很大,但实际上并不是溢出。注意:可以很好地表示pow(21000)