错误乘以大的双打

问题描述 投票:0回答:3

我用C ++制作了一个使用双打的BOMDAS计算器。每当我输入一个表达式时

1000000000000000000000*1000000000000000000000

我得到的结果如1000000000000000000004341624882808674582528.000000。我怀疑它与浮点数有关。

c++ math double
3个回答
0
投票

浮点数表示具有固定大小表示的值。 double可以表示16位十进制数字,其中十进制数字可以恢复(在内部,它通常使用基数2存储值,这意味着它可以准确地表示大多数小数十进制值)。如果超过位数,则将适当地舍入该值。当然,结果是你不一定会得到你希望的数字:如果你明确地或隐含地要求超过16位十进制数字(例如通过将格式设置为std::ios_base::fixed,其数字大于1e16 )格式化将会产生更多的数字:它将准确地表示内部保持的二进制值,我认为这可能产生54个非零数字。

如果要精确计算大值,则需要一些可变大小的表示。由于您的值是整数,因此可以使用大整数表示。与double相比,计算速度通常要慢得多。


0
投票

双精度存储53位。这大约是15位小数。您的问题是double无法存储您尝试存储的位数。十五位数后的数字将不准确。


0
投票

那不是错误。这正是由于浮点类型的表示方式,因为结果精确到double精度。

计算机中的浮点类型以(-1)符号*尾数* 2exp的形式写入,因此它们只有更宽的范围,而不是无限的精度。它们仅精确到尾数精度,并且每次操作后的结果将被舍入。 double类型最常用的是IEEE-754 64位双精度和53位尾数,所以它可以正确记录(253)≈15.955十进制数字。做1e21*1e21会产生1e42,当以double精度舍入到最接近的值时,会给出你看到的值。如果将其四舍五入为16位,则与1e42完全相同。

如果您需要更多射程,请使用doublelong double。如果你只使用整数,那么int64_t(或者带有gcc的__int128和64位平台上的许多其他编译器)具有更大的精度(64/128位与53位相比)。如果您需要更高的精度,请使用arbitrary-precision arithmetic库,例如GMP

© www.soinside.com 2019 - 2024. All rights reserved.