The JVM has no choice: it must faithfully implement the IEEE floating-
point spec (http://en.wikipedia.org/wiki/IEEE_754-2008), which
specifies limited precision. By asking it to use floats, you are
demanding that it accept rounding errors. If you want precision, there
are lots of ways to get it; the most common is to cast everything up
to integers and perform the computation there, then convert back down
later:

user=> (def numbers [12.305 12.3049])
#'user/numbers
user=> (/ (apply - (map #(int (* 10000 %)) numbers)) 10000)
1/10000

Or you can tell Java to use BigDecimals, which have arbitrary
precision:
user=> (- 12.305M 12.3049M)
0.0001M

You could use clojure's excellent ratio type instead:
user=> (def nums (map #(/ % 10000) [123050 123049]))
#'user/nums
user=> nums
(2461/200 123049/10000)
user=> (apply - nums)
1/10000

Computers don't lie; they just do what you tell them to.

On Oct 12, 9:17 am, cej38 <junkerme...@gmail.com> wrote:
> I keep running into this type of problem:
>
> user=> (- 12.305 12.3049)
> 9.999999999976694E-5
>
> The computer (probably the JVM) has just lied to me.  Any fourth grade
> student will know that this does not equal 0.0001.  This would be less
> of a problem is the JVM was consistent; if it were consistent then the
> following equality would be true:
>
> user=> (= 0.0001 (- 12.305 12.3049))
> false
>
> Now it has lied to me again!
>
> I need a method to reliably compare two numbers.  My first choice
> would be to have the JVM compute (- 12.305 12.3049) correctly.
> Barring that, I need a way to, without fail, compute the truthfulness
> of the following: =, <, >, <=, >=.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to