LISP - 小数点后位数(LISP - digits after decimal point)

2019-07-31 00:57发布

没有人知道如何到小数点Lisp的一个浮动后指定的位数NUMER?

说,如果我在REPL打印此命令:

CL-USER 3 > (format t "~,15f" (float (/ 1 7)))

我得到:

0.142857150000000 

但数量在小数点后第8位四舍五入,我需要看到很多数字的小数点后才能看到,如果数字是循环的计算周期。 (其实我开始尝试和解决项目欧拉的问题26)。

我需要这样的:

CL-USER 3 > (format t "~,15f" (float (/ 1 7)))
0.142857142857142857142857142857142857.... 

谢谢,

卢卡

Answer 1:

Common Lisp中没有花车,在其标准的任意正确性。

Common Lisp的定义了在标准四种浮子类型: SHORT-FLOATSINGLE-FLOATDOUBLE-FLOATLONG-FLOAT

可以强迫一个比使用的功能的浮COERCE (例如在LispWorks):

CL-USER 1 > (coerce (/ 1 7) 'double-float)
0.14285714285714285D0

或作为LONG-FLOAT在CLISP

[1]> (coerce (/ 1 7) 'long-float)
0.14285714285714285714L0

要计算你需要扩展Common Lisp的长浮点数。 GNU CLISP具有非移植的扩展,并可以设置的(二进制)位的数目:

(SETF (EXT:LONG-FLOAT-DIGITS) n)

例:

[3]> (SETF (EXT:LONG-FLOAT-DIGITS) 1000)    
1000
[4]> (coerce (/ 1 7) 'long-float)
0.142857142857142857142857142857142857142857142857142857
142857142857142857142857142857142857142857142857142857
142857142857142857142857142857142857142857142857142857
142857142857142857142857142857142857142857142857142857
142857142857142857142857142857142857142857142857142857
142857142857142857142857142857142857143L0


Answer 2:

除了雷纳的出色答卷,我想你想检查出功能合理 :

(rationalize (float 1/7))
1/7


Answer 3:

您还可以通过手,哪里还需要值不再那么长很长很长做除法(这被称为是太长了一些编译器;)事情是这样的:

(defun divide (a b &key (precision 8))
  (let ((fractional 0))
    (multiple-value-bind (whole reminder)
        (floor a b)
      (unless (zerop reminder)
        (dotimes (i precision)
          (setf reminder (* reminder 10))
          (multiple-value-bind (quot rem)
              (floor reminder b)
            (setf fractional (+ (* fractional 10) quot))
            (when (zerop rem) (return))
            (setf reminder rem))))
      (values whole fractional))))

(multiple-value-call #'format t "~d.~d~&" (divide 1 7))
(multiple-value-call #'format t "~d.~d~&" (divide 1 7 :precision 54))

;; 0.14285714
;; 0.142857142857142857142857142857142857142857142857142857

可能有更有效的方法来计算小数部分,但它们太复杂(对我来说,并会在这个例子中)。



文章来源: LISP - digits after decimal point