Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Equals for case class with floating point fields

Is it ok, to create case classes with floating point fields, like:

case class SomeClass(a:Double, b:Double) 

I guess auto generated equal method won't work in this case. Is overriding equals the best solution?

EDIT:

if overriding equals is the way to go, I would like to avoid hardcoding epsilon ( where epsilon is defined like => |this.a-a|< epsilon). This won't compile:

case class SomeClass(a:Double, b:Double, implicit epsilon:Double)  

I am looking for a way to pass epsilon without passing concert value each time (some "implicit" magic).

I have also follow up more general question, how would you define hashcode for class with only floating point fields?

like image 862
Blezz Avatar asked Dec 15 '22 09:12

Blezz


1 Answers

You are correct. If you are worried about precision, then you will need to override equals:

case class SomeClass(a:Double, b:Double)
SomeClass(2.2 * 3, 1.0) == SomeClass(6.6, 1.0)
// res0: Boolean = false

case class BetterClass(a: Double, b: Double) {
  override def equals(obj: Any) = obj match {
    case x: BetterClass =>
      (this.a - x.a).abs < 0.0001 && (this.b - x.b).abs < 0.0001   
    case _ => false
  }
}
BetterClass(2.2 * 3, 1.0) == BetterClass(6.6, 1.0)
// res1: Boolean = true
like image 122
dbyrne Avatar answered Dec 29 '22 12:12

dbyrne