11

由于实现 AP 小数有两种方法,一种是模拟double数据类型的存储和行为,仅使用更多字节,另一种是使用现有的整数 APA 实现将小数表示为有理数,即作为一对整数,分子和分母,这两种方法中哪一种更有可能在性能方面提供有效的算术?(内存使用确实是次要问题。)

我知道现有的 C/C++ 库,其中一些提供带有“浮点数”的分数 APA,而另一些则提供有理数(但是它们都没有定点 APA),当然我可以对依赖于“ float" 实现与使用合理实现的实现相比,但结果将在很大程度上取决于那些特定库的实现细节,我必须从近十个可用的库中随机选择。因此,我感兴趣的两种方法(如果考虑定点 APA,则为三种)更具理论上的优缺点。

4

5 回答 5

10

问题是您在标题中提到的任意精度是什么意思。这是否意味着“任意,但在编译时预先确定并在运行时固定”?或者它是否意味着“无限,即在运行时可扩展以表示任何有理数”?

在前一种情况下(在编译时可定制精度,但之后修复)我会说最有效的解决方案之一实际上是定点算术(即您提到的两个都不是)。

首先,定点算术不需要任何用于基本算术运算的专用库。它只是一个覆盖在整数算术上的概念。这意味着,如果您真的需要点后的很多数字,您可以使用任何大整数库,将所有数据乘以 2^64,然后您基本上可以立即得到 64 位二进制数字的定点运算点(至少只要涉及算术运算,对乘法和除法进行一些额外的调整)。这通常比浮点或有理表示更有效。

另请注意,在许多实际应用中,乘法运算通常伴随着x = y * a / b相互“补偿”的除法运算(如 ),这意味着通常不需要对此类乘法和除法进行任何调整。这也有助于提高定点运算的效率。

其次,定点算术在整个范围内提供统一的精度。这对于浮点或有理表示都不是这样,在某些应用程序中,这可能是后两种方法的一个重大缺点(或好处,取决于您的需要)。

所以,再一次,你为什么只考虑浮点和有理表示。有什么东西阻止你考虑定点表示吗?

于 2012-08-03T16:47:03.523 回答
4

由于似乎没有其他人提到这一点,因此有理数和浮点数代表不同的数字集。该值1/3可以用有理数精确表示,但不能用浮点数表示。即使是任意精度的浮点数也需要无限多的尾数位来表示重复的小数,例如1/3. 这是因为浮点数实际上类似于有理数,但分母被限制为 2 的幂。任意精度的有理数可以表示任意精度浮点数可以表示的所有内容,甚至更多,因为分母可以是任何整数,而不仅仅是幂2.(也就是说,除非我严重误解了任意精度浮点数是如何实现的。)

这是为了回应您对理论利弊的提示。

我知道您没有询问内存使用情况,但这里有一个理论比较,以防其他人感兴趣。如上所述,有理数专门研究可以简单地用分数表示法表示的数字,例如1/3or 492113/203233,而浮点数专门研究可以简单地用 2 次方的科学记数法表示的数字,例如5*2^45or 91537*2^203233。以它们各自的人类可读形式表示数字所需的 ascii 输入量与它们的内存使用量成正比。

如果我有任何错误,请在评论中纠正我。

于 2015-09-28T15:16:07.630 回答
2

无论哪种方式,您都需要任意大小的整数相乘。这将是您性能的主要因素,因为它的复杂性比O(n*log(n)). 诸如对齐操作数和加减大整数之类的事情是O(n),所以我们将忽略这些。

对于简单的加法和减法,您不需要浮点数的乘法*和有理数的 3 次乘法。花车赢了。

对于乘法,浮点数需要 1 次乘法,有理数需要 2 次乘法。花车有优势。

除法有点复杂,理性可能会在这里获胜,但这绝不是确定的。我会说这是平局。

所以总的来说,恕我直言,加法至少O(n*log(n))适用于有理数和O(n)浮点数这一事实显然使浮点表示获胜。

*如果您的指数基数和数字基数不同,您可能需要一次乘法来执行加法。否则,如果您使用 2 的幂作为基数,则对齐操作数需要移位。如果您不使用 2 的幂,那么您可能还需要乘以一位数,这也是一种O(n)运算。

于 2012-08-03T16:19:59.940 回答
0

您实际上是在问这个问题:“我需要和我选择的动物一起参加比赛。我应该选择乌龟还是蜗牛?”。

第一个建议“模拟双精度”听起来像是交错精度:使用一个双精度数组,其和是定义的数字。Douglas M. Priest 有一篇论文“Algorithms for Arbitrary Precision Floating Point Arithmetic”描述了如何实现这种算法。我实现了这一点,但我的经验非常糟糕:进行此运行所需的开销会使性能下降 100-1000 倍!使用小数的另一种方法也有严重的缺点:您需要实现 gcd 和 kgv 不幸的是,分子或分母中的每个素数都有很好的机会破坏您的数字并破坏您的表现。

因此,根据我的经验,它们是性能最差的选择。

我推荐使用 MPFR 库,它是 C 和 C++ 中最快的 AP 包之一。

于 2012-10-16T14:38:56.463 回答
-1

有理数不会给出任意精度,而是给出确切的答案。然而,它们在存储方面更昂贵,并且使用它们的某些操作变得昂贵,并且根本不允许某些操作,例如取平方根,因为它们不一定会产生合理的答案。

就个人而言,我认为在您的情况下,AP 浮动会更合适。

于 2012-08-03T16:05:05.067 回答