Reputation: 2660
consider below method:
fun main() {
var costs = 0
var transactionFee = 1.325
var total = (costs + transactionFee).toRoundedUpDouble()
}
fun Double.toRoundedUpDouble(fraction: Int = 2) =
BigDecimal(this).setScale(fraction, RoundingMode.HALF_UP).toDouble()
I want a number with 2 decimal after the comma, rounded up from 5. e.g. 1.325 becomes 1.33. This works when I add a round number, but not when I don't:
Output:
5.00 + 1.325 becomes 6.33 = good
5 + 1.325 becomes 6.33 = good
1 + 1.325 becomes 2.33 = good
1.325 becomes 1.32 = NOT GOOD
0 + 1.325 becomes 1.32 = NOT GOOD
0.00 + 1.325 becomes 1.32 = NOT GOOD
0.000 + 1.325 becomes 1.32 = NOT GOOD
This thread doesn't answer my question.
Upvotes: 1
Views: 106
Reputation: 37749
You say that this thread doesn't answer your question, but I it really does.
As mentioned in that thread, double literals lie to you, and println
as well.
To know the actual value that these literals give you, you can use BigDecimal
this way:
println(BigDecimal(1.325)) // 1.3249999999999999555910790149937383830547332763671875
println(BigDecimal(0 + 1.325)) // 1.3249999999999999555910790149937383830547332763671875
println(BigDecimal(5 + 1.325)) // 6.32500000000000017763568394002504646778106689453125
If you want accurate results, use BigDecimal
from the start, and make sure to initialize them with strings, not double literals:
fun main() {
var costs = BigDecimal.ZERO
var transactionFee = BigDecimal("1.325")
var total = (costs + transactionFee).roundedUp()
println(total) // 1.33
println(total.toDouble()) // 1.33
}
fun BigDecimal.roundedUp(fraction: Int = 2) = setScale(fraction, RoundingMode.HALF_UP)
Upvotes: 4