Я мог бы воспроизвести эту проблему.
def roundWithScala(d: Double): Double = {
BigDecimal(d).setScale(3, RoundingMode.HALF_UP).doubleValue()
}
def roundWithJava(d: Double): Double = {
val bd = new java.math.BigDecimal(d).setScale(3, java.math.RoundingMode.HALF_UP)
return bd.doubleValue()
}
println(roundWithScala(8407.3555)) //8407.356
println(roundWithJava(8407.3555)) //8407.355
println(roundWithScala(8409.3555)) //8409.356
println(roundWithJava(8409.3555)) //8409.355
println(roundWithScala(8409.4555)) //8409.456
println(roundWithJava(8409.4555)) //8409.456
Первое, что я заметил, что Scala использует diffrent MathContext
чем Java.
Я попытался использовать тот же MathContext.UNLIMITED
в обоих, но ничего не изменил.
Потом я заметил, что в BigDecimal
java`s SCALA в BigDecimal строится так:
new BigDecimal(new BigDec(java.lang.Double.toString(d), mc), mc)
Я попытался использовать его в Java:
val bd = new java.math.BigDecimal(java.lang.Double.toString(d), java.math.MathContext.UNLIMITED).setScale(3, java.math.RoundingMode.HALF_UP)
и я получил тот же результат (8409.356
).
Итак, в основном причина, по которой вы получаете отличный результат, состоит в том, что double преобразуется в строку в конструкторе scala.
Возможно, вы могли бы использовать BigDecimal java в вашем случае (как в roundWithJava
)?
Как вы генерируете '8409.3555', чтобы перейти к' round'? Оба раза в Скала? Вы пробовали называть Java 'round' от Scala и наоборот? –
Я генерирую как двойной «Double d = 8409.3555;» –