带舍入模式的DecimalFormat.HALF-UP



有一个简单的代码

import java.math.RoundingMode
import java.text.DecimalFormat

fun main(args: Array<String>) {
val f = DecimalFormat("#.##").apply { roundingMode = RoundingMode.HALF_UP }
println(f.format(-0.025f))
println(f.format(-0.015f))
println(f.format(-0.005f))
println(f.format(0.005f))
println(f.format(0.015f))
println(f.format(0.025f))
}

我得到了以下输出:

-0,03<--ok

-0,01<--预期-0.02

-0<--预期-0.01

0<--预期0,01

0,01<---预期0,02

0,03<--ok

我是否正确理解RoundingMode.HALF_UP的含义?

p。S.我发现,使用doubles而不是float可以解决问题。因此println(f.format(0.005.toDouble()))起作用,给出了预期的0.1

文档中关于RoundingMode.HALF_UP的说明是:

取整模式向"最近的邻居"取整,除非两个邻居等距,在这种情况下取整。

虽然这看起来像您正在寻找的行为,但这些都是十进制浮点,很难在内存中表示。甲骨文网站上有一篇关于它的精彩文章。

因此,-0.005和-0.015似乎比其他任何东西都更接近(最近的邻居(-0.01,所以它们都被格式化为-0.01。让你的代码做你想做的事,就是把你的舍入模式改为:

roundingMode = RoundingMode.UP

运行的输出是:

-0.03
-0.02
-0.01
0.01
0.02
0.03

这正是你所期望的。如果你确实想让你的代码工作,你可以使用以下方法:

import java.math.BigDecimal
import java.math.RoundingMode
import java.text.DecimalFormat
fun main(args: Array<String>) {
val f = DecimalFormat("#.##").apply { roundingMode = RoundingMode.HALF_UP }
println(f.format( BigDecimal("-1000.045")))
println(f.format( BigDecimal("-1000.035")))
println(f.format( BigDecimal("-1000.025")))
println(f.format( BigDecimal("-1000.015")))
println(f.format( BigDecimal("-1000.005")))
}

如果希望显示精确的数字,请永远不要使用floatdouble。如果进行舍入并希望舍入发生在实心基础上,则不希望使用floatdouble;-(

使用double的样本也会给出错误的结果。使用BigDecimal的样本将给出您期望的结果。所以……如果你想安全的话,就坚持使用BigDecimal

fun main(args: Array<String>) {
val f = DecimalFormat("#.##").apply { roundingMode = RoundingMode.HALF_UP }
println(f.format(BigDecimal("-0.025")))
println(f.format(BigDecimal("-0.015")))
println(f.format(BigDecimal("-0.005")))
println(f.format(BigDecimal("0.005")))
println(f.format(BigDecimal("0.015")))
println(f.format(BigDecimal("0.025")))
}

最新更新