public class doublePrecision {
public static void main(String[] args) {
double total = 0;
total += 5.6;
total += 5.8;
System.out.println(total);
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码打印:
11.399999999999
Run Code Online (Sandbox Code Playgroud)
我怎么才能打印(或能够用它)11.4?
我遇到了两种不同的浮点数精度公式.
⌊(N-1)log 10(2)⌋= 6位小数(单精度)
和
N log 10(2)≈7.225十进制数字(单精度)
其中N = 24个有效位(单精度)
第一个公式位于由W. Kahan教授撰写的" IEEE标准754二进制浮点运算 " 第4页的顶部.
第二个公式可以在维基百科文章" 单精度浮点格式 "的IEEE 754单精度二进制浮点格式:binary32下找到.
对于第一个公式,W.Kahan教授说
如果十进制字符串最多为6 sig.(分解). 转换为Single,然后转换回相同数量的sig.dec.,那么最后的字符串应该与原始字符串匹配.
对于第二个公式,维基百科说
...总精度为24位(相当于log 10(2 24)≈7.225十进制数字).
两个公式(6和7.225十进制数字)的结果是不同的,我希望它们是相同的,因为我假设它们都是为了表示最有效的十进制数字,可以转换为浮点二进制,然后转换回来十进制,其开头的有效十进制数字相同.
为什么这两个数字不同,什么是最重要的十进制数字精度可以转换为二进制并返回到十进制而不会失去重要性?
floating-point binary decimal significant-digits floating-point-precision
以下方法调用中的第二个调用setYCoordinate(),得到的值不正确-89.99999435599995而不是-89.99999435599994.
第一次调用setXCoordinate()得到正确的值29.99993874900002.
setXCoordinate(BigDecimal.valueOf(29.99993874900002))
setYCoordinate(BigDecimal.valueOf(-89.99999435599994))
Run Code Online (Sandbox Code Playgroud)
我在BigDecimal.valueOf()中放了一个断点 - 这个方法的代码如下所示 -
public static BigDecimal valueOf(double val) {
// Reminder: a zero double returns '0.0', so we cannot fastpath
// to use the constant ZERO. This might be important enough to
// justify a factory approach, a cache, or a few private
// constants, later.
return new BigDecimal(Double.toString(val));
}
Run Code Online (Sandbox Code Playgroud)
valueOf收到的参数即"双val"本身在检查时为-89.99999435599995.为什么?我在Maven pom.xml中设置了Java版本,如下所示
<java.version>1.8</java.version>
Run Code Online (Sandbox Code Playgroud) 我想将double值格式化为6位精度而不进行舍入.
格式化为6位小数后的预期值
20790123833965.960938
Run Code Online (Sandbox Code Playgroud)
我尝试过使用十进制格式
DecimalFormat formatter = new DecimalFormat("#0.000000");
System.out.println(formatter.format(hashValue) );
Run Code Online (Sandbox Code Playgroud)
我得到了这个
20790123833965.960000
Run Code Online (Sandbox Code Playgroud)