我用C ++制作了一个使用双打的BOMDAS计算器。每当我输入像
这样的表达式时1000000000000000000000*1000000000000000000000
我得到的结果如1000000000000000000004341624882808674582528.000000。我怀疑它与浮点数有关。
答案 0 :(得分:0)
浮点数表示具有固定大小表示的值。 double
可以表示16位十进制数字,其中可以恢复十进制数字(在内部,它通常使用基数2存储该值,这意味着它可以准确地表示大多数小数十进制值)。如果超过位数,则将适当地舍入该值。当然,结果是你不一定得到你希望的数字:如果你明确地或隐含地要求超过16位十进制数字(例如通过将格式设置为std::ios_base::fixed
的数字,大于1e16
)格式化将会产生更多的数字:它将准确地表示内部保持的二进制值,我认为这可能产生54个非零数字。
如果要精确计算大值,则需要一些可变大小的表示。由于您的值是整数,因此可以使用大整数表示。与double
相比,计算速度通常要慢得多。
答案 1 :(得分:0)
双重存储53位精度。这大约是15位小数。您的问题是double无法存储您尝试存储的位数。第15位十进制数后的数字将不准确。
答案 2 :(得分:0)
这不是错误。这正是由于浮点类型的表示方式,因为结果精确到double
精度。
计算机中的浮点类型以( - 1) sign * mantissa * 2 exp 的形式编写,因此它们只有<强>范围更广,而不是无限精度。它们仅精确到尾数精度,并且每次操作后的结果将被舍入。 double
类型最常被实现为IEEE-754 64位双精度,具有53位尾数,因此记录(2 53 )≈15.955十进制数字是正确的。执行1e21*1e21
会产生1e42
,当以二次精度四舍五入到最接近的值时,会得到您看到的值。如果将其四舍五入为16位,则与1e42完全相同。
如果您需要更多范围,请使用double
或long double
。如果你只使用整数,那么int64_t
(或__int128
与gcc和64位平台上的许多其他编译器)具有更大的精度(64/128位与53位相比)。如果您需要更加精确,请使用arbitrary-precision arithmetic库,例如GMP