Kotlin BigInteger 到 BigDecimal 转换

Kotlin BigInteger to BigDecimal conversion

我正在写一个非常简单的 class,我正在努力做一些小数除法。

所以这不是很好的代码但是...

class Rational (val numerator: BigInteger, val denominator: BigInteger) : Comparable <Rational> {

     //ATTEMPT 1
     //val decimalRepresentation: BigDecimal = (numerator.toBigDecimal().div(denominator.toBigDecimal()))//.setScale(5)

     //ATTEMPT 2  
     val decimalRepresentation = (BigDecimal(numerator).div(BigDecimal(denominator))) //.setScale(5)

     override fun compareTo(other: Rational): Int {
        val a = BigDecimal(1.0)
        val b = BigDecimal(2.0)
        val x = a.divide(b) // 0.5
        println ("x: " + x.toString())

        println("this val: " + this.decimalRepresentation)
        println("other val: " + other.decimalRepresentation)

        return when {
           ...
        }
    }

所以我尝试了两种将 BigIntegers 转换为 BigDecimals 的方法来进行比较,但都失败了,数学执行整数除法

所以

1 / 3 = 0
5 / 6 = 1

我做了一个 poc 以防我发疯并且 x 是 0.5。

谁能告诉我如何解决这个问题(不更改参数类型或转换为字符串并返回!)

奇怪的是 1 / 2 也返回 0,这对我来说似乎很奇怪,因为我希望 0.5 舍入为 1?这让我担心我在某处完全遗漏了一个非常简单的点!

问题之一在于 BigDecimal.div. It uses the RoundingMode.HALF_EVEN and the given scale of the used dividend BigDecimal (which is also stated in the documentation). The other problem is that the BigInteger to BigDecimal-transformation first sets the scale to 0 (check also BigDecimal(BigInteger)),因此它会在不使用小数位的情况下四舍五入。

另请注意,在您的示例中,您首先使用 a.divide(b) 和两个 BigDecimal,而在实际转换中,您使用 a.div(b) 和两个 BigInteger-转换后的 BigDecimal.那是完全不同的故事 ;-)

您可以通过以下方式之一解决您的问题:

使用 toBigDecimal 转换您的 BigInteger 并指定所需的 scale,例如:

val scale = 10 // decimal digits
val decimalRepresentation = numerator.toBigDecimal(scale) / denominator.toBigDecimal(scale)

或者您可能想改用 divide 并传递所需的比例:

val decimalRepresentation = BigDecimal(numerator).divide(BigDecimal(denominator), 2, RoundingMode.HALF_UP)

在这种情况下,我使用了 2 个十进制数字,我是 rounding up on half (RoundingMode.HALF_UP)