Domanda

I am working on a piece of code where numerical equality is an important factor in several logical conditional. Clojure is doing something I dont know enough about to explain. For example:

user=> (- 5 4.9)
0.09999999999999964
user=> (- 5 4.8)
0.20000000000000018
user=> (- 5 2.9)
2.1
user=> (- 5 2.7)
2.3
user=> (- 5 2.8)
2.2
user=> (- 9 6.9)
2.0999999999999996 
user=> (- 9 2.9)
6.1

It seems like in some circumstance, Clojure numerics understands subtraction to 0.1, in other cases not. What is going on here?

È stato utile?

Soluzione

By default these results are expressed as decimals, with the inherent rounding errors. You can switch to using BigDecimals by suffixing with the letter M:

user=> (- 5M 4.9M)
0.1M
user=> (- 5M 4.8M)
0.2M
user=> (- 9M 6.9M)
2.1M
user=> (- 9M 2.9M)
6.1M

To do the same with a variable that's a decimal, use the bigdec form:

user=> (def k 4.9)
#'user/k
user=> (- 5M k)
0.09999999999999964
user=> (- 5M (bigdec k))
0.1M

Altri suggerimenti

Adding some Ms to the number literals in question addresses the symptoms, but does nothing to improve David's understanding of the fundamentals of floating-point math. See the classic What Every Computer Scientist Should Know About Floating-Point Arithmetic, or any one of the numerous questions on SO about floating-point inexactness. Here are two examples I could easily find; I've seen at least three for Clojure alone, but it's hard to find them with a search.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top