c ++ pow(2,1000)对于double来说是正常的,但它正在发挥作用.为什么?

0xb*_*0de 16 c c++ numbers

代码:

#iclude <math.h>

int main(){
double somenumber = pow(2, 1000);
printf("%lf\n", somenumber);
return 0;
}
Run Code Online (Sandbox Code Playgroud)

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

这显然是双重的.它是如何工作的?

Dav*_*men 31

这显然是双重的.它是如何工作的?

2 1000在可以用双精度表示的数字范围内.所以这个数字显然不会太大.

我怀疑你所说的"太大"的意思是打印的位数远远大于可以存储在双倍中的16位数字.要求计算机打印超过16位十进制数字并没有错.假设这些额外的数字有任何意义,这是错误的.

在这种特殊情况下,打印的数字完全正确.那是因为电脑pow(2,some_int)特别对待.2的幂可以精确地表示为双精度.用于计算精确积分值的十进制表示的算法将给出完全正确的十进制表示.

所有其他的,所有的赌注都关闭了.更改您的程序,以便打印3 646例如:

#include <math.h>
#include <stdio.h>

int main(){
  double somenumber = pow(3, 646);
  printf("%lf\n", somenumber);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

它仍会打印一个很长的数字,但只有前16个左右的数字才是正确的.

  • 是的,计算十进制表示是`printf`的一部分,而不是`double`变量值的固有属性.'printf`显示的值只需要在第一个`DECIMAL_DIG`位置正确,即使2 ^ 1000具有精确表示为`double`.一个好的实现将打印确切的值,但这样做是非常重要的,并且计算时间和空间相当昂贵. (3认同)

Hao*_*hun 13

doubleexp通常有11bit(-1022~1023标准化),事实为52bit,标志为1bit.因此它不会太大.有关更多说明,请参阅维基百科上的IEEE 754

  • @ltsik标准化浮点数保存为1.xxxx*2 ^ yyyyy.其中xxx称为事实部分,yyyy称为exp部分.这不是大多数情况下的数字(当数字在二进制表示中无限重复时,就像十进制的1/3一样.或者它不会无限重复,但根本不适合xxxx的分配位). (2认同)
  • @Itsik:换句话说,浮点是计算机做科学记数法的方式.2 ^ 1000不需要1000位来表示它.`double`通过存储基数(2)和指数(1000)来存储2 ^ 1000.显然,存储2和1000需要远小于1000位. (2认同)
  • @Itsik:如果你想能够表示*0和(2 ^ 1000)-1之间的每个整数*,你需要1000位.这与浮点类型形成对比; "double"可以表示的值的范围不是连续的.例如,你不能将`1/3'完全存储在`double`中. (2认同)