c++的pow(2,1000)对于double来说通常太大了,但它正在工作.为什么

c++ pow(2,1000) is normaly to big for double, but it's working. why?

本文关键字:大了 常太 工作 为什么 pow 1000 double 对于 c++      更新时间:2023-10-16

代码:

#iclude <math.h>
int main(){
double somenumber = pow(2, 1000);
printf("%lfn", somenumber);
return 0;
}

我得到这个巨大的数字:10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376

对于double来说,这显然太大了。它是如何工作的?

对于double来说,这显然太大了。它是如何工作的?

21000在可以用双精度数表示的数字范围内。因此,对于双精度浮点数来说,这个数显然不是太大。

我怀疑你所说的"太大"是指输出的位数远远大于可存储在双精度型中的16位左右。要求计算机打印超过16个十进制数字并没有错。错误的是假设这些额外的数字有任何意义。

在这种特殊情况下,打印的数字是完全正确的。这是因为计算机对pow(2,some_int)有特殊的处理。2的幂可以精确地用双精度数表示。用于计算精确整数值的十进制表示的算法将给出完全正确的十进制表示。

其他的都是无效的。修改你的程序,使其输出3646,例如:

#include <math.h>
#include <stdio.h>
int main(){
  double somenumber = pow(3, 646);
  printf("%lfn", somenumber);
  return 0;
}

它仍然会打印一个大的长数字,但是只有前16位左右的数字是正确的。

double通常有11bit的exp(-1022~1023归一化),52bit的fact和1bit的sign。因此它不会太大。有关更多说明,请参见Wikipedia上的IEEE 754

它是2的幂,而浮点数本质上是存储为2的(倍数)幂。

同样地,在十进制系统中,精确地表示101000只需要很少的空间,这应该不会让你感到惊讶,但这种简洁的符号不可能表示其他数值的大幂次,比如31000 =1322070819480806636890455259752144365965422032752148167664920368226828597346704899540778313850608061963909777696872582355950954582100618911865342725257953674027620225198320803878014774228964841274390400117588618041128947815623094438061566173054086674490506178125480344405547054397038895817465368254916136220830268563778582290228416398307887896918556404084898937609373242171846359938695516765018940588109060426089671438864102814350385648747165832010614366132173102768902855220001。