Any ideas of how to compare two Double values prop...
# multiplatform
t
Any ideas of how to compare two Double values properly on multiplatform?
e
what do you mean by that?
m
Isn’t that a pure Kotlin question which is unrelated to multiplatform or not?
t
Well, comparing double and float values shouldn't be done with ==. For example (0.1 + 0.2) == 0.3 returns with false and strangely that's all right. For Java there are a few solutions to this, I was wondering if there are any for multiplatform. I've spend almost 5 hours working/reading on this, it's... complex to say at least. I ended up with this code (the *1000 is something I decided on):
Copy code
fun Double.compareToDelta(other: Double) : Int {
    val epsilon = max(this.ulp, other.ulp) * 1000
    return when {
        abs(this - other) <= epsilon -> 0
        this < other -> -1
        this > other -> 1
        this.isNaN() && other.isNaN() -> 0
        else -> 0
    }
}
For more info: https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ https://www.gamedevs.org/uploads/numerical-robustness-geometric-calculations.pdf
I'm not sure if it is purely Kotlin or not to be honest. Double depends on a lot of things, hardware, implementation, VM... dunno.
r
for handling prescision errors easiest way is to round the numbers to a fixed number of decimal places. otherwise you could use expect/actual to make a class that uses the platform specific Decimal class (e.g. jvm BigDecimal, ios Decimal) https://stackoverflow.com/questions/1458633/how-to-deal-with-floating-point-number-precision-in-javascript
t
Hm, it might be a good idea for my application to go with Long and simply say that there are 6 decimal places and that's it. Thanks, I might of been focused too much on floating point. BigDecimal libraries are nice but they have drawbacks I wanted to avoid. Most notably they are about 100 times slower.
r
also a simple way to round is to multiply , cast to int and divide eg
(x * 1000).toInt()/1000.0