有一个简单的代码
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")))
}
如果希望显示精确的数字,请永远不要使用float
或double
。如果进行舍入并希望舍入发生在实心基础上,则不希望使用float
或double
;-(
使用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")))
}