手动Math.pow()使用float丢失精度

时间:2013-08-18 16:36:59

标签: c math double precision

我正在尝试在C中执行手动功能(相当于Math.pow()),所以在这里,它是:41619^6

  float sum = 41619;
  float a = sum;
  int k;
  for (k = 0; k < 5; k++) {
    sum = sum * a;
  }
  printf("%f", sum);
  // sum should be 41619 ^ 6 now

然而,我在这里失去了精确度。我得到5196966085285475633789403136,答案应为5196965646007524312007756281

我尝试将总和更改为double,但我仍在失去精确度。

如何在不使用Math.pow()的情况下实现这一点(对于我尝试运行的测试来说速度太慢),并且不会丢失精度?

1 个答案:

答案 0 :(得分:0)

您似乎想computations on Big Integers。 Big Integer是一个整数,其值大于2^64。计算机体系结构本身不支持Big Integers,因为它们需要比CPU中的寄存器更多的位。在每种计算机语言中使用Big Integers的方法有很多种。对于C,您必须使用库。

我推荐GNU Multiple Precision(GMP)库。它通常预先安装有大多数C编译器,仅需要#include <gmp.h>和编译器标志-lgmp

阅读GMP manual以获取支持的大量功能列表。

许多,许多,许多合作的思想与更明确的优化焦点然后你或我在这个应用领域拥有的已经使GMP库尽可能高效,而不会损失精度。

应该注意,pow()通常在协处理器中使用硬件查找表,并且仅限于浮点数。对于以浮点形式表示的非常大的数字,这可能导致明显的不精确性。 Big Integer库将使用各种数学技术来最大化计算效率,而不会失去exponentiation by squaring等精度。

当标准车轮出现故障时,不会重新发明车轮,只需寻找一个不同的,更专业的车轮。