我只有几行代码C ++:
long re = 103491683;
double temp = (double)re * (double)re;
cout<<"\n"<<"double * double = \t"<<(long)temp;
long temp2 = re * re;
cout<<"\n"<<"long * long = \t\t"<<temp2;
并返回2个不同的值:
double * double = 10710528450172488
long * long = 10710528450172489
我无法理解发生了什么,我在java上遇到了这个bug,我也尝试过C ++和那个问题。请帮帮我(抱歉我的英语不好)
答案 0 :(得分:1)
double
个数字有64位存储空间。在那些64中,1用于存储符号,11用于存储指数,53存储用于十进制数字。这意味着您可以达到的最大精确度是15.95十进制数53 * log10(2)。
您的电话号码10,710,528,450,172,489有17位十进制数字,因而略微超出double
中可达到的精度。
在64位系统上签名long
中可以达到的最大数量是2 ^ 63 - 1 =
9,223,372,036,854,775,807,大于你的数字。
答案 1 :(得分:0)
double
类型具有52个二进制位的精度,其他位用于存储指数,一个用于存储符号。 long
类型(在大多数64位系统上)具有63位精度,一个用于存储符号。在double * double
计算中,您丢失了最不重要的位。
请参阅https://en.wikipedia.org/wiki/IEEE_floating_point
更准确地说,这个例子:https://en.wikipedia.org/wiki/Double-precision_floating-point_format
答案 2 :(得分:0)
由于数字在内部的存储方式,双打有一定的不精确性。当您使用双精度进行数学运算时,这种不精确性可能会更复杂。如果您的代码需要能够处理小数位并且这是一个不可接受的错误量,请考虑使用允许更大十进制数的库。如果re
的所有可能值总是整数,那么长版本应该可以正常工作。