【发布时间】:2012-07-22 22:08:07
【问题描述】:
我正在做一些数字运算,这需要高精度算术。我正在使用 GNU MP 库,according to the GMP manual:
“浮点数或简称Float,是具有有限精度指数的任意精度尾数。”
虽然尾数应该具有任意精度,但我仍然遇到精度问题。与其用我的实际代码让你厌烦,不如用一个近乎最小的工作示例来说明我的问题。代码计算 9.3^15、9.8^15 和 (9.3*9.8)^15。在我的机器上,(9.3^15)*(9.8^15) 和 (9.3*9.8)^15 的值从第 16 位开始开始不同,在这种情况下导致(大约)4.94* 的错误10^13。
任何帮助将不胜感激。代码如下。
#include <gmp.h>
#include <gmpxx.h>
#include <iostream>
#include <iomanip>
int main()
{
mpf_class x, y, z;
x = y = z = 1.0;
for (int i = 0; i < 15; i++)
{
x *= 9.3;
y *= 9.8;
z *= 9.3*9.8;
}
std::cout << z - x*y << std::endl;
return 0;
}
【问题讨论】:
-
9.3和9.8不能用二进制精确表示。 -
这似乎只是 15 的幂,而不是 100 的幂。
-
你是对的 DeadMG。我使用的是 100 的幂,但后来意识到 15 足以说明我的观点。已编辑。
-
@Mystical:感谢您的评论。老实说,我不明白你为什么这么说,但如果它有所不同,问题仍然存在于 93 和 98 上。这些只是整数 - 当然它们可以精确表示。
-
由于
9.3和9.8在double中无法表示,因此当它们被精确扩展到您想要的任何GMP 精度时,它们将保持+/- 10^-16错误。这是主要问题。如果它不适用于偶数整数,那么还有一个单独的问题。我怀疑您没有正确使用该库,但我没有使用 GMP,所以我无法判断。