使用C ++进行数学计算,错误的答案

时间:2012-09-06 21:10:49

标签: c++ c math calc

  

可能重复:
  Precision loss with double C++

我正在尝试使用C ++进行一些计算,但是它没有按预期工作,例如当我运行一个非常简单的代码时,如下面的代码,

int main()
{
    double a = 93548387.09678;
    double b = a * a;
    printf("result is: %f \n", b);     
}

它将结果显示为:8751300728408995.000000而不是:8751300728408994.7970863684

如何解决此问题?

10 个答案:

答案 0 :(得分:13)

您将看到16位有效数字,这与您从典型double获得的数字大致相同:尾数有53位,2 53 约为10位 16 (或者更确切地说,log 10 (2 53 )= 15.955)。

换句话说,两个数字 相同,四舍五入为16位有效数字。


鉴于评论中的反馈,或许我应该强调,即使变量a实际上没有值93548387.09678。它将具有与该数字最接近的可表示的值,但这不相同。真的没有“确切结果”这样的东西;一切都只是一个精确的问题。

如果您确实需要精确计算,则需要使用不同的数据类型:十进制浮点类型(但那些也具有固定的,有限的精度),或任意精度的十进制浮点库,或任意-precision rational-number library。

答案 1 :(得分:4)

这是一个非常常见的问题。

读取。了解。记忆。

http://floating-point-gui.de/

答案 2 :(得分:4)

如果你真的需要更高的精确度,你必须为此编写自己的类,或者你可以尝试找到一个。

答案 3 :(得分:2)

双精度浮点数仅具有15-17个十进制数字的精度。见"Double-precision floating-point format"

  

这给出了15到17个有效小数位数。

如果您需要比double提供的更精确的话,请参阅此question

答案 4 :(得分:2)

正如上面许多人所说,double的精确度不足以满足您的要求。它们也是C和C ++标准中最精确的东西,因此您将不得不使用第三方库。

一个好的解决方案是使用GNU MP - GNU多精度库。语法不会很可爱,但这是C ++可用文字太小的自然效果。

答案 5 :(得分:1)

您需要比double提供的更重要的数据。

如果您需要更高的精确度,请查看arbitrary-precision arithmetic library

答案 6 :(得分:1)

根据您的实施情况,long double可能会提供比double更正确的有效数字。因此,你甚至可能得到一些正确的小数(但你不可能得到任何常见实现的确切答案,see example)。

如果您需要更高的精度(或“无限”精度),则必须使用任意精度的算术库,例如GMP。

答案 7 :(得分:0)

可悲的是,你做不到。 Double仅保留16个最高有效位的正确精度,这正是它将你切断的地方。

答案 8 :(得分:-2)

%f用于浮点数,%Lf用于双打

printf("result is: %Lf \n", b);

http://www.cplusplus.com/reference/clibrary/cstdio/printf/

答案 9 :(得分:-4)

检查printf的格式,然后尝试float not double

printf