LISP-小数点后的数字

LISP-小数点后的数字,lisp,common-lisp,number-formatting,Lisp,Common Lisp,Number Formatting,有人知道如何在Lisp中指定浮点小数点后的位数吗 假设我在REPL处打印此命令: CL-USER 3 > (format t "~,15f" (float (/ 1 7))) 我得到: 0.142857150000000 但是这个数字是在小数点后的第8位四舍五入的,我需要在小数点后看到很多数字,以查看这个数字是否是循环的,并计算周期。 (事实上,我开始尝试解决欧拉计划的问题26) 我需要这样的东西: CL-USER 3 > (format t "~,15f" (float (/

有人知道如何在Lisp中指定浮点小数点后的位数吗

假设我在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.... 
谢谢,


Luca

Common Lisp在其标准中没有任意精确的浮点

Common Lisp在标准中定义了四种浮点类型:
SHORT-float
SINGLE-float
DOUBLE-float
LONG-float

您可以使用函数
强制
(LispWorks中的示例)将比率强制为浮点:

或作为CLISP中的
长浮点

[1]> (coerce (/ 1 7) 'long-float)
0.14285714285714285714L0
要使用较长的浮点数进行计算,需要对Common Lisp进行扩展。具有不可移植的扩展名,可以设置(二进制)位数:

例如:

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

除了雷纳出色的回答, 我想你想看看这个功能:


您也可以手动进行除法,在这种情况下,您仍然需要比long更长的值(这对于某些编译器来说太长了;)如下所示:

(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

可能有更有效的方法来计算分数部分,但它们太复杂了(对我来说,就是这个例子)。

谢谢,这真的很有帮助。
(rationalize (float 1/7))
1/7
(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