我知道double
存在一些精确问题,它可以在转换为integer
期间截断值。
就我而言,我正在分配double
690000000000123455 ,并在分配期间更改为 690000000000123392 。
为什么数字变化如此剧烈?毕竟没有分配它的小数部分。它看起来不像精度问题,因为值不会改变1而是63。
答案 0 :(得分:4)
假设您将690000000000123455存储为64位整数并将其指定为double。
double d = 690000000000123455;
可以在此处检查最接近的可表示的双精度值690000000000123455:http://pages.cs.wisc.edu/~rkennedy/exact-float?number=690000000000123455并且可以看作是690000000000123392。
换句话说,一切都是预料之中的。您的数字不能完全表示为双精度值,因此选择最接近的可表示值。
有关浮点数据类型的更多讨论,请参阅:Is floating point math broken?
答案 1 :(得分:2)
IEEE-754双精度浮点数约为53 bits of precision,相当于约16个十进制数字(给定或取值)。你会注意到你的两个数字开始分歧的地方。
答案 2 :(得分:0)
double
存储大小为8个字节。它的值范围从2.3E-308到1.7E + 308。它的精度高达15位小数。但是你的号码包含18位数字。这就是原因。
您可以使用long double
,因为它的精度高达19位小数。
答案 3 :(得分:0)
其他答案已经非常完整,但我想建议一个网站,我发现它非常有助于理解浮点数如何工作:IEEE 754 Converter(这里只有32位浮点数,但交互仍然非常好)。
正如我们所看到的,690000000000123455介于2^59
和2^60
之间,对于双精度,尾数的最高精度为2^-52
,这意味着给定数字的精确步长是2^7=128
。您提供的错误63实际上在范围内。
作为一个辅助建议,最好使用long
来存储大整数,因为它将保持精度并且不会溢出(在您的情况下)。