Reputation: 163
In Kotlin, BigDecimal division returns strange results.
BigDecimal(1.0) / BigDecimal(2.0)
// returns 0.0
// Just like Int(1) / Int(2) returns 0
But:
BigDecimal(1.1) / BigDecimal(2.0)
// returns 0.55
// Just like Double(1.1) / Double(2.0) returns 0.55
So why does that happen and how can I make 1.0 / 2.0
returns 0.5 with BigDecimal without using divide()
giving a scale parameter?
UPDATES:
Here are the complete codes:
Welcome to Kotlin version 1.2.41 (JRE 1.8.0_172-b11)
Type :help for help, :quit for quit
>>> import java.math.BigDecimal
>>> BigDecimal(1.0) / BigDecimal(2.0)
0
>>> BigDecimal(1.1) / BigDecimal(2.0)
0.550000000000000044408920985006261616945266723632812
UPDATES 2:
According to @user2864740
BigDecimal(1.0).divide(BigDecimal(2.0))
// returns 0.5
and
BigDecimal("1.0") / BigDecimal(2.0)
// returns 0.5
So the results are confusing. For BigDecimals, why do 1.0 / 2.0
returns 0.0, 1.0.divide(2.0)
returns 0.5, and "1.0" / 2.0
returns 0.5?
Upvotes: 12
Views: 5253
Reputation: 41753
1.1
is a double
literal
A floating-point literal is of type float if it ends with the letter F or f; otherwise its type is double and it can optionally end with the letter D or d.
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
Therefore by the time the value is passed to BigDecimal
you already lost precision due to the double
value. BigDecimal(1.1)
is equivalent to double d = 1.1; BigDecimal(d)
. You need to pass the value as string
BigDecimal("1.1")
unless the value is exactly representable as a double like 1.5
Upvotes: 2
Reputation: 89528
If you write divide
explicitly, it will work the same way as it does in Java:
val a = BigDecimal(1.0)
val b = BigDecimal(2.0)
val x = a.divide(b) // 0.5
When you use the /
operator, that translates to the BigDecimal.div
extension from the standard library, which does the following:
Enables the use of the / operator for BigDecimal instances.
The scale of the result is the same as the scale of this (divident), and for rounding the RoundingMode.HALF_EVEN rounding mode is used.
You can take a look at how the different RoundingMode
constants work here.
Upvotes: 10