存储和使用C中1,000,000个有效数字的浮点数的最有效方法是什么?

时间:2009-10-05 23:39:26

标签: c math floating-point

我正在编写一个实用程序来计算π到十进制后的一百万位数。在32位或64位消费者桌面系统上,存储和使用如此大量精确到百万位数的最有效方法是什么?

澄清:语言为C。

8 个答案:

答案 0 :(得分:9)

忘记浮点数,需要表示整数的位串

每个数字需要少于1/2兆字节。 “高效”可能意味着许多事情。空间高效?时间效率?易于编程?

你的问题被标记为浮点,但我很确定你根本不想要浮点数。浮点的整个想法是我们的​​数据仅为一些有意义的数字所知,甚至物理和化学的着名常数也只是少数或两个数字。因此,保持合理数量的数字然后只记录指数是有意义的。

但你的任务完全不同。您必须考虑每一位。鉴于此,没有浮点或十进制算术包将起作用,除非它是一个模板,你可以任意大小,然后指数将是无用的。所以你也可以使用整数。

你真正需要的是一串比特。这只是一组方便的类型。我建议<stdint.h>并简单地使用uint32_t[125000](或64)开始。这实际上可能是对该标题中更加模糊的常量的一种很好的用法,它可以选择在给定平台上快速的位大小。

更具体地说,我们需要更多地了解您的目标。这是用于特定语言的练习吗?对于数论的一些调查?如果是后者,为什么不使用已经支持Bignum的语言,比如Ruby?

然后存储是别人的问题。但是,如果您真正想要的是实现一个大数字包,那么我可能会建议使用bcd(4位)字符串或甚至普通的ascii 8位字符串和可打印数字,因为事情会更容易编写和调试最大的空间和时间效率可能并不重要。

答案 1 :(得分:3)

我建议将其存储为一个短整数的数组,每个数字一个,然后仔细编写实用程序类来添加和减去部分数字。你将最终从这个int数组移动到浮点数和返回数,但是你需要一种“完美”的方式来存储数字 - 所以请使用它的精确表示。就空间而言,这不是最有效的方式,但是一百万个整数并不是很大。

这就是你使用表示的方式。决定你将如何“使用”这个数字,并编写一些很好的实用功能。

答案 2 :(得分:2)

如果您愿意以十六进制而不是十进制来容忍计算pi,那么可以使用very cute algorithm来计算给定的十六进制数字而不知道之前的数字。通过扩展,这意味着您不需要存储(或能够进行计算)百万位数字。

当然,如果你想得到第n个十进制数字,你需要知道所有十六进制数字到那个精度才能进行基本转换,所以根据你的需要,这最终可能不会为你节省太多(如果有的话)。

答案 3 :(得分:1)

除非你纯粹为了娱乐和/或学习而写这篇文章,否则我建议你使用像GNU Multiprecision这样的库。查看mpf_t数据类型及其相关函数,以存储任意精度浮点数。

如果您只是为了娱乐/学习而这样做,那么将数字表示为chars的数组,每个数组元素存储一个十进制数字。你必须实现长加法,长乘法等。

答案 4 :(得分:1)

尝试PARI/GP,请参阅wikipedia

答案 5 :(得分:1)

您可以将其小数位数作为文本存储在文件中,并将其映射到数组。

答案 6 :(得分:0)

我曾经使用过一个使用非常大数字的应用程序(但不需要很好的精度)。我们所做的是将数字存储为对数,因为你可以在int中存储一个相当大的数字作为log10。

在求助于位填充或一些复杂的位表示之前,请先考虑这一行。

我对复杂的数学运算不太满意,但我认为在存储具有数百万位精度的数字时,有一些优雅的解决方案。

答案 7 :(得分:0)

IMO,任何精确算术的程序员都需要了解基本转换。这解决了两个问题:能够以十六进制数字计算pi并将这些东西转换为十进制表示,以及找到最佳容器。

主导约束是乘法指令中正确位的数量 在Javascript中,一个总是具有53位精度,这意味着可以原生处理具有最多26位数的Uint32Array。 (每个字浪费6位)。

在使用C / C ++的32位架构中,可以轻松获得A * B mod 2 ^ 32,这表明16位的基本元素。 (这些可以在从MMX开始的许多SIMD架构中并行化)。此外,每个16位结果每个字可以包含4位十进制数(浪费大约2.5位)。