0

我了解使用二进制(或 binaryoid)浮点并以十进制表示结果时的复杂性:

1 (do ((numerator 1 (* 10 numerator)))
 2     ((>= numerator 1000000000000))
 3   (let ((fred (list 'coerce (/ numerator 3) (quote 'double-float))))
 4     (prin1 fred)
 5     (princ " ")
 6     (prin1 (eval fred))
 7     (terpri)))
(COERCE 1/3 'DOUBLE-FLOAT) 0.3333333333333333d0
(COERCE 10/3 'DOUBLE-FLOAT) 3.3333333333333335d0
(COERCE 100/3 'DOUBLE-FLOAT) 33.333333333333336d0
(COERCE 1000/3 'DOUBLE-FLOAT) 333.3333333333333d0
(COERCE 10000/3 'DOUBLE-FLOAT) 3333.3333333333335d0
(COERCE 100000/3 'DOUBLE-FLOAT) 33333.333333333336d0
(COERCE 1000000/3 'DOUBLE-FLOAT) 333333.3333333333d0
(COERCE 10000000/3 'DOUBLE-FLOAT) 3333333.3333333335d0
(COERCE 100000000/3 'DOUBLE-FLOAT) 3.3333333333333332d7
(COERCE 1000000000/3 'DOUBLE-FLOAT) 3.333333333333333d8
(COERCE 10000000000/3 'DOUBLE-FLOAT) 3.3333333333333335d9
(COERCE 100000000000/3 'DOUBLE-FLOAT) 3.3333333333333332d10

但我希望避免最后一个可变数字的不合理性。在这种情况下,计算速度对我来说并不重要。

那里是否存在任何真正的十进制浮点 LISP 包?

编辑 1:理想情况下,这个包将允许任意精度,就像 bignum 对整数一样。

编辑 2,回应 Dennis Jaheruddin 的问题:

[I]如果您对最后一位不感兴趣,而只是希望数字相同,您可能只想观察前 15 位左右的数字?

我想到了那个。它行不通。例如,在 2/3 的情况下,我想要 666667 之类的东西。我看到的是:

 1 (do ((numerator 2 (* 10 numerator)))
 2     ((>= numerator 1000000000000))
 3   (let ((fred (list 'coerce (/ numerator 3) (quote 'double-float))))
 4     (prin1 fred)
 5     (princ " ")
 6     (prin1 (eval fred))
 7     (terpri)))
(COERCE 2/3 'DOUBLE-FLOAT) 0.6666666666666666d0
(COERCE 20/3 'DOUBLE-FLOAT) 6.666666666666667d0
(COERCE 200/3 'DOUBLE-FLOAT) 66.66666666666667d0
(COERCE 2000/3 'DOUBLE-FLOAT) 666.6666666666666d0
(COERCE 20000/3 'DOUBLE-FLOAT) 6666.666666666667d0
(COERCE 200000/3 'DOUBLE-FLOAT) 66666.66666666667d0
(COERCE 2000000/3 'DOUBLE-FLOAT) 666666.6666666666d0
(COERCE 20000000/3 'DOUBLE-FLOAT) 6666666.666666667d0
(COERCE 200000000/3 'DOUBLE-FLOAT) 6.6666666666666664d7
(COERCE 2000000000/3 'DOUBLE-FLOAT) 6.666666666666666d8
(COERCE 20000000000/3 'DOUBLE-FLOAT) 6.666666666666667d9
(COERCE 200000000000/3 'DOUBLE-FLOAT) 6.6666666666666664d10

如您所见,我什至无法使用最后一位来确定是否四舍五入;64 舍入到 60,而不是 70。但我可以丢弃最后一个数字并使用前一个数字来舍入其余的数字。不过,我对此感到不舒服,因为(a)此时我开始放弃很多精度,并且(b)我不确定这是否会导致舍入错误的方式. 十进制浮点包,最好具有任意精度,将是理想的。

编辑 3:正如 Rainer Joswig 在下面的回答中指出的那样,一个不可移植的潜在解决方案是设置浮点精度。对于那些在家跟随的人,他在这里指出,这样做是这样的:(SETF (EXT:LONG-FLOAT-DIGITS) n)

编辑 4:在他回答后的评论中,Rainer Joswig 建议研究代数系统 Maxima 和 Axiom。这样做会导致这些优秀的维基百科资源:

编辑5:我已经确定我不需要十进制浮点包,但我仍然很好奇是否有一个。可能没有。

为什么我不需要一个?答案是(a)Rainer Joswig 指向 wu-decimal 包的指针和(b)wvxvw 提到长除法的组合。

虽然 wu-decimal 没有常规特征和尾数使用以 10 为基数,但它确实引入了一个有趣的想法:将数字存储为比率。所以 1/3 存储为 1/3,而不是重复的(对于有限长度)二进制分数。尽管将存储为比率的数字相乘很快就会产生相当长的比率,但始终保持原始精度。我将使用这个想法。我不需要的是 wu-decimal 在适当的时候非常漂亮地解析和写入比率作为十进制数,所以我不会安装该软件包。如果您有兴趣简化这些值的解析和写入,请查看包。(我没用过。)

那么,剩下的就是将比率打印为十进制数。为此,我将使用长除法,就像 wvxvw 一样。我的代码有些不同,但是对于长除法的想法,我非常感谢他。

4

1 回答 1

1

没用过:

http://wukix.com/lisp-decimals

在 GNU CLISP 中,您可以设置浮点精度。

于 2012-10-10T18:48:54.947 回答