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
)。
我正在写一个非常简单的 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
)。