为什么(长)9223372036854665200d给我9223372036854665216?

Pac*_*ier 9 java double casting long-integer

我知道有精确错误的怪异东西,但我无法理解,

为什么(long)9223372036854665200d要给我9223372036854665216

NPE*_*NPE 34

9223372036854665200d是类型的常量double.但是,9223372036854665200不适合double不失精度.A double只有52位的尾数,而有问题的数字需要63位才能准确表示.

最接近double9223372036854665200d是尾数等于1.1111111111111111111111111111111111111111111110010100二进制且其指数为63(十进制)的数字.这个号码就是9223372036854665216(称之为U).

如果我们将尾数减少一个等级1.1...0011,我们得到9223372036854664192(称之为L).

原始数字介于L和之间,U并且U比它更接近L

最后,如果你认为这个尾数的截断应该导致一个以一串零结尾的数字,那么你是对的.只有它发生在二进制,而不是十进制:U在基16是0x7ffffffffffe5000L0x7ffffffffffe4c00.


use*_*421 16

因为双打没那么精确.你为什么这么奇怪?将d更改为l.

  • @Pacerier'Doubles没有那么多精确度'实际上完全解释了它.双精度具有53位精度,即15.9十进制数,小于您的数字. (3认同)

ty1*_*824 6

Doubles具有52-53位精度,而a long具有64位精度(仅适用于整数).double中的精度损失用于表示指数,其允许double表示比long罐更大/更小的数字.

您的号码长度为19位,而双号码只能存储大约16位(十进制)整数数据.因此最终的数字最终被舍入.

参考:双 - 维基百科


Kev*_*vin 5

因为双打精度有限.你的常数有一个比双重记录更多的有效数字,所以它会失去它们.