2012-08-16 113 views
5

沒有人知道如何指定小數點後位數的Lisp中的浮點數?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.... 

謝謝

盧卡

回答

17

Common Lisp中沒有花車,在其標準的任意正確性。

Common Lisp定義了標準中的四種浮點類型:SHORT-FLOAT,SINGLE-FLOAT,DOUBLE-FLOAT,LONG-FLOAT

可以使用函數COERCE(例如LispWorks)強迫的比例爲float:

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

或作爲在CLISP

LONG-FLOAT

不同,需要較長的浮點數計算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 
+0

謝謝,這真的很有幫助。 – Luca 2012-08-16 11:36:46

3

除了雷納的出色答卷, 我想你想檢查出功能RATIONALIZE

(rationalize (float 1/7)) 
1/7 
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 

可能有更有效的方法來計算小數部分,但它們太複雜(對我而言,並且將用於這個例子)。

相關問題