Common lisp 十进制浮点包

Common lisp 十进制浮点包,common-lisp,gnu-common-lisp,Common Lisp,Gnu Common Lisp,我理解使用二进制(或二进制)浮点并以十进制表示结果时的复杂性: 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))

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

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,回答丹尼斯·杰鲁丁的问题:

[一] f您对最后一个数字不感兴趣,只想知道 如果数字相同,您可能只想观察前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在下面的回答中指出的,一个不可移植的潜在解决方案是设置浮点精度。对于那些在国内跟随的人,他指出这是这样做的:

编辑4:在回答后的评论中,雷纳·约斯维格建议研究代数系统的极大值和公理。这样做可以获得这些优秀的维基百科资源:

  • 文章
  • 文章
  • 那篇文章的章节
  • 那篇文章的部分,大部分链接指向软件列表
编辑5:我已经决定不需要十进制浮点包,但我仍然好奇是否有十进制浮点包。可能没有

为什么我不需要一个呢?答案是(a)雷纳·乔斯维格(Rainer Joswig)指向wu十进制包的指针和(b)wvxvw提到长除法的组合

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

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

从未使用过它:


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

也许问题不在于转换为浮点,而在于分数中使用的数字的重要性?在这种情况下,您可能希望从不同的方向进行搜索。另外,如果您对最后一个数字不感兴趣,只是希望数字相同,您可能只想观察前15个左右的数字?丹尼斯,谢谢您的回答。请看问题中的编辑2。一方面,这是一个令人兴奋的软件包。我会把它下载下来转一转。另一方面,它不足以涵盖,比如说,我的样本案例。谢谢你,雷纳,这会很有用的。但我仍在寻找原始问题的答案。:)我在问题中添加了将浮点精度设置为edit3的想法。谢谢。@Mariposa的Bill Evans-另一个选择:在Common Lisp之上的一些数学软件包应该有必要的基础设施:Maxima和Axiom。谢谢你的指点。在这个问题上,他们的答案是4。