Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Floating point accuracy in Clojure

I am trying to learn Clojure and tried defining this simple function:

user=> (defn triple [arg] (* 3 arg))
#'user/triple
user=> (triple 1)
3
user=> (triple 1.01)
3.0300000000000002

Can anyone explain why there is a 2 at the end of the result here?

like image 961
user1147851 Avatar asked Jul 08 '26 00:07

user1147851


2 Answers

Due to the representation of floating point numbers on computers, operations on these numbers are not precise. It applies both to JVM and physical machines. See Floating point inaccuracy examples for a longer discussion. There's also a comprehensive article What Every Computer Scientist Should Know About Floating-Point Arithmetic linked in the answers to that question.

like image 197
Jan Avatar answered Jul 11 '26 05:07

Jan


It's due to floating point inaccuracy, which affects all languages with floating point representations. There are some values that cannot be accurately represented with floating point numbers.

Fortunately, Clojure also has support for high precision numerics, so you can do:

(defn triple [arg] (* 3 arg))
(triple 1.01M)
=> 3.03M

Note the use of "M" at the end of numeric constants to indicate that you want to use high precision numbers. In this case java.math.BigDecimal numbers are used by Clojure under the hood.

like image 29
mikera Avatar answered Jul 11 '26 07:07

mikera