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