具有简单的代码
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 <-好的
-0,01 <-预期-0,02
-0 <-期望-0,01
0 <-期望为0.01
0,01 <---期望0,02
0,03 <-好的
我是否正确理解RoundingMode.HALF_UP
的含义?
PS
我发现,使用双精度代替浮点数可以解决问题。因此println(f.format(0.005.toDouble()))
可以正常工作,并提供预期的0.1
。
答案 0 :(得分:1)
文档中关于RoundingMode.HALF_UP
的内容是:
除非两个邻居都等距,否则舍入模式将朝“最近的邻居”舍入。
虽然看起来像您想要的行为,但是它们是十进制浮点数,它们很难在内存中表示。在the Oracle site上有很多读物。
因此,似乎-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")))
}
答案 1 :(得分:0)
如果要显示准确的数字,切勿使用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")))
}