Scala FAQ: I need to compare two floating-point numbers in Scala, but as in some other programming languages, two floating-point numbers that should be equivalent may not be; how do I comparison floating-point numbers?
Solution
As in Java and many other languages, you solve this problem by creating a method that lets you specify the precision for your comparison. The following Scala “approximately equals” method demonstrates the approach:
def ~=(x: Double, y: Double, precision: Double) = { if ((x - y).abs < precision) true else false }
You can use this method like this:
scala> val a = 0.3 a: Double = 0.3 scala> val b = 0.1 + 0.2 b: Double = 0.30000000000000004 scala> ~=(a, b, 0.0001) res0: Boolean = true scala> ~=(b, a, 0.0001) res1: Boolean = true
Discussion
When you begin working with floating-point numbers in programming, you quickly learn that 0.1
plus 0.1
is 0.2
:
scala> 0.1 + 0.1 res2: Double = 0.2
But 0.1 plus 0.2 isn’t exactly 0.3:
scala> 0.1 + 0.2 res3: Double = 0.30000000000000004
This subtle inaccuracy makes comparing two floating-point numbers a real problem:
scala> val a = 0.3 a: Double = 0.3 scala> val b = 0.1 + 0.2 b: Double = 0.30000000000000004 scala> a == b res4: Boolean = false
As a result, you end up writing your own functions to compare floating-point numbers with a precision (or tolerance).
As you saw in Recipe 1.11 of the Scala Cookbook, you can define an implicit conversion to add a method like this to the Double
class. This makes the following code very readable:
if (a ~= b) ...
Or, you can add the same method to a utilities object, if you prefer:
object MathUtils { def ~=(x: Double, y: Double, precision: Double) = { if ((x - y).abs < precision) true else false } }
You can then invoke that method like a static method in Java:
println(MathUtils.~=(a, b, 0.000001))
With an implicit conversion, the name ~=
is very readable, but in a utilities object like this that name doesn’t look right, so it might be better named approximatelyEqual
, equalWithinTolerance
, or some other name.
this post is sponsored by my books: | |||
#1 New Release |
FP Best Seller |
Learn Scala 3 |
Learn FP Fast |