Kotlin BigInteger到BigDecimal的转换

时间:2018-11-12 12:55:22

标签: java kotlin biginteger bigdecimal

我正在编写一个非常简单的类,并且正在努力进行十进制除法。

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

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

我已经疯了,以防我生气并且x为0.5。

谁能告诉我如何解决此问题(无需更改参数类型或转换为字符串然后返回!)

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

1 个答案:

答案 0 :(得分:3)

问题之一在于BigDecimal.div。它使用RoundingMode.HALF_EVEN和使用的股息scale的给定BigDecimal(在文档中也有说明)。另一个问题是从BigIntegerBigDecimal的转换首先将小数位设置为0(也请检查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)