基于this stackoverflow post,我希望以下内容打印出0.59,而不是0.60。
import java.math.RoundingMode;
import java.text.DecimalFormat;
public class Test {
public static void main(String[] args) {
double toFormat = 0.6;
DecimalFormat formatter = new DecimalFormat("########0.00");
formatter.setRoundingMode(RoundingMode.DOWN);
System.out.println(formatter.format(toFormat)); // 0.60
}
}
0.60的最接近浮点表示形式是0.59999999999999997779553950749686919152736663818359375,该数值低于0.6。在Java 8中将DecimalFormat设置为RoundingMode.DOWN时,为什么不将其四舍五入为0.59?
最佳答案
因为格式代码知道double
的精度。
请参见类shouldRoundUp(...)
中方法java.text.DigitList
的source code中的注释:
为了避免转换时错误的双舍入或截断
文本的二进制双精度值,有关准确性的信息
转换结果在FloatingDecimal中的值,以及任何
在该类中需要四舍五入。
对于以下HALF_DOWN,HALF_EVEN,HALF_UP舍入规则:
在格式化float或double的情况下,我们必须考虑
在二进制到十进制中说明FloatingDecimal做了什么
转换。
考虑平局情况,FloatingDecimal可能会将
值(低于此值时,返回等于tie的十进制数字),
或将值“截断”到领带之上,而值超过领带,
或在二进制值可以是时提供准确的十进制数字
在给定格式的情况下,精确地转换为其十进制表示形式
FloatingDecimal的规则(因此,我们有一个精确的十进制
二进制值的表示形式)。
如果将双二进制值完全转换为十进制数
值,则DigitList代码必须应用预期的舍入
规则。
如果FloatingDecimal已经舍入了十进制值,
DigitList不应在以下任何一个中再次舍入该值
上面的三种取整模式。
如果FloatingDecimal已将十进制值截断为
以“ 5”结尾的数字,DigitList应将以下值四舍五入
上面所有三个舍入模式。
仅当数字在maximumDigits索引处时才必须考虑这一点
恰好是一组数字中的最后一个,否则有
该位置之后的剩余数字,我们不必考虑
FloatingDecimal做了什么。
其他舍入模式不受这些平局情况的影响。
对于总是转换为精确数字的其他数字
(例如BigInteger,Long等),则传递的hasRounded布尔值
必须设置为false,并且allDecimalDigits必须设置为
在上层DigitList调用堆栈中为true,提供正确的状态
对于那些情况..