问题描述
我已经获取了10位浮点值,并试图将其转换为字符串以可读格式打印。这是要检查的程序
public static void main(String[] args) {
String s1 = "2139095039";
String s2 = "2.13909504E9";
Float f1 = Float.valueOf(s1);
Float f2 = Float.valueOf(s2);
System.out.println("Are f1 and f2 are same:::" + (f1.equals(f2)));// TRUE
System.out.println("Are s1 and s2 are same:::" + (s1.equals(s2)));// FALSE
System.out.println("Are f1 and f2 string format type same:::"
+ (String.format("%.0f",f1)).equals(String.format("%.0f",f2)));// TRUE
System.out.println("S1 Float to String convertion:: " + String.format("%.0f",f1));// 2139095040
System.out.println("S2 Float to String convertion:: " + String.format("%.0f",f2));// 2139095040
}
我的问题是,当S1和S2值相同时,为什么在转换为字符串后键入其printig 2139095040 而不是 2139095039 ?
换句话说,我该如何打印人类可读的科学符号 2.13909504E9 的格式?
解决方法
出于同样的原因,0.333333333333333333333 * 3
不是1.0。舍入错误。
更具体地说。
- 计算机浮点类型为以2为底
- 这是一个数学事实,即(有限精度)以2为底的浮点与十进制表示法(以10为底)之间的映射并非对所有值都精确。 (就像您不能以十进制表示法精确地写1/3 一样……除非您有无限张纸。)
观察:
- 您可以使用
double
而不是float
来减少舍入错误。 - 您可以使用
BigDecimal
进一步减少舍入错误。 - 通过显示精度较低的数字并四舍五入到最接近的值,可以隐藏输出的舍入错误。
- 在某些情况下,您无法完全消除舍入误差。
请注意,存在一个专门用于数值计算的数学领域:“数值分析”。如果您真的想了解这些内容,那么如何处理错误对计算的影响,那就是要研究的领域。