I want to develop a Common Lisp solution to Leetcode problem 50. "Pow(x, n)" which asks:
"Implement pow(x, n), which calculates x raised to the power n (i.e., x^n)."
My direct solution is :
(defun pow (x n)
(declare (ftype (function (double-float fixnum) double-float) pow))
(if (zerop n)
1d0
(let ((r 1d0))
(dotimes (i (abs n)) (setf r (* r x)))
(if (plusp n)
r
(/ 1d0 r)))))
(pow 2.1d0 3)
=> 9.261000000000001d0
Why does it have a 1 at the 15th digit after period ? How can I get the result without this rounding error ?
My Common Lisp implementation : SBCL 2.3.4 on linux.
Calculating with floats is not exact. Even representing numbers as floats is not exact. 1/3 is 0.3333..., where a float on a computer has limited precision.
In Common Lisp one can compute with integers and rational numbers.
Your code, but more general:
(defun pow (x n)
(if (zerop n)
1
(let ((r 1))
(dotimes (i (abs n)) (setf r (* r x)))
(if (plusp n)
r
(/ 1 r)))))
Now your 2.1
might mean 21/10
, which is a number in Common Lisp.
CL-USER 7 > (pow 21/10 3)
9261/1000
We can then convert the result to a double float:
CL-USER 8 > (float * 1.0d0)
9.261D0