How to compare floating point values in Scala?

Spread the love

Question Description

As far as I know, exact comparison doesn’t make much sense with floating point values as what is intended to be 0.0001 can actually be something like 0.0001000…0001… Should I implement my own comparison function to specify precision or is there a common practice for this?

I used to use the following with C# (which, I suspect, is still wrong as a Double value can be probably uncapable of representing 0.0001 at all, even set as a constant (as Michael Borgwardt explained here)):

public static bool AlmostEquals(this double x, double y, double precision = 0.0001)
{
  if (precision < 0.0)
    throw new ArgumentException();

  return Math.Abs(x - y) <= precision;
}

Should I do something alike in Scala?

Practice As Follows

Yes, you can do the same thing as in Java. You could also use some of Scala's cool features and pimp the Double class with a ~= method that takes an implicit precision parameter that only needs to be specified once.

scala> case class Precision(val p:Double)
defined class Precision

scala> class withAlmostEquals(d:Double) {
  def ~=(d2:Double)(implicit p:Precision) = (d-d2).abs <= p.p
}
defined class withAlmostEquals

scala> implicit def add_~=(d:Double) = new withAlmostEquals(d)
add_$tilde$eq: (d: Double)withAlmostEquals

scala> 0.0~=0.0
:12: error: could not find implicit value for parameter p: Precision
              0.0~=0.0
                 ^

scala> implicit val precision = Precision(0.001)
precision: Precision = Precision(0.001)

scala> 0.0 ~= 0.00001
res1: Boolean = true

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.