As I understand it, Kotlin has operator overloading for BigDecimal instances. https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/java.math.-big-decimal/
Why can't I actually use it in my program ? Is there some special import I need to do to get this working ? I couldn't understand why it chose to round up to 0.2.
import java.math.BigDecimal
fun main() {
val num = BigDecimal("15.5")
val den = BigDecimal("100")
val operatorDivide = num/den
println("Operators- 15.5/100 is: $operatorDivide") // 0.2
val fnDivide = num.divide(den)
println("Functions- 15.5/100 is: $fnDivide") // 0.155
val fnDiv = num.div(den)
println("Operator fun ? 15.5/100 is: $fnDiv") // 0.2
}
div
(aka /
) is implemented as
public inline operator fun BigDecimal.div(other: BigDecimal): BigDecimal =
this.divide(other, RoundingMode.HALF_EVEN)
This calls divide(BigDecimal,RoundingMode)
, which does something different from the divide(BigDecimal)
overload that you are calling in your code.
divide(BigDecimal,RoundingMode)
keeps the scale of this
:
Returns a
BigDecimal
whose value is(this / divisor)
, and whose scale isthis.scale()
.
but divide(BigDecimal)
only specifies what the preferred scale is.
Returns a
BigDecimal
whose value is(this / divisor)
, and whose preferred scale is(this.scale() - divisor.scale())
The preferred scale doesn't have to be strictly followed by division - at the top of the JavaDocs page, just below the table showing the preferred scales for each operation, it says:
These scales are the ones used by the methods which return exact arithmetic results; except that an exact divide may have to use a larger scale since the exact result may have more digits. For example, 1/32 is 0.03125.
The "scale" of a BigDecimal
created using BigDecimal(String)
constructor is basically "how many decimal places it has" - 15.5
has scale 1, and 100
has scale 0.
div
maintains the scale of the result as 1
, so the result is rounded to 0.2. 0.155 would need a scale of at least 3 to represent. divide(BigDecimal)
sets the preferred scale to 1, too, but since the exact result can be represented with a scale of 3, the result of divide
has scale 3.