LISP - digits after decimal point

Does anyone know how to specify the number of digits after the decimal point for a float in Lisp?

Say if I print this command in REPL:

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

I get:

0.142857150000000 

But the number is rounded to the eighth digit after the decimal point, I need to see many digits after the decimal point to see if the number is cyclic and calculate the period. (Actually, I'm starting to try to solve the Project Euler 26 problem).

I need to get something like this:

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

Thank,

Luca

+5
source share
3 answers

Generic Lisp do not have floats with arbitrary precision in their standard.

Common Lisp defines four types of floating-point standard: SHORT-FLOAT, SINGLE-FLOAT, DOUBLE-FLOAT, LONG-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
+17

Rainer , , 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

There may be more efficient ways of calculating the fractional part, but they are too complicated (for me they will be for this example).

+3
source

All Articles