java8 numberformat,NumberFormat舍入问题仅限Java 8
Holger..
19
我可以將這個問題追溯到java.text.DigitList第522行.
情況是,它認為十進制數字6.0289已經四舍五入(與等效BigDecimal表示相比,這是正確的6.208899…)并且決定不再向上舍入.問題是這個決定只有在四舍五入產生的數字的情況下才有意義5,而不是在它大于的情況下5.請注意代碼如何HALF_DOWN正確區分digit=='5'和digit>'5'案例.
顯然,這是一個錯誤,并且是一個奇怪的錯誤,因為執行類似權限的代碼(僅針對另一個方向)正好在破壞的代碼之下.
case HALF_UP:
if (digits[maximumDigits] >= '5') {
// We should not round up if the rounding digits position is
// exactly the last index and if digits were already rounded.
if ((maximumDigits == (count - 1)) &&
(alreadyRounded))
return false;
// Value was exactly at or was above tie. We must round up.
return true;
}
break;
case HALF_DOWN:
if (digits[maximumDigits] > '5') {
return true;
} else if (digits[maximumDigits] == '5' ) {
if (maximumDigits == (count - 1)) {
// The rounding position is exactly the last index.
if (allDecimalDigits || alreadyRounded)
/* FloatingDecimal rounded up (value was below tie),
* or provided the exact list of digits (value was
* an exact tie). We should not round up, following
* the HALF_DOWN rounding rule.
*/
return false;
else
// Value was above the tie, we must round up.
return true;
}
// We must round up if it gives a non null digit after '5'.
for (int i=maximumDigits+1; i
if (digits[i] != '0') {
return true;
}
}
}
break;
這不會發生在另一個數字上的原因是,這6.2088不是四舍五入的結果(再次,與BigDecimal輸出相比6.208800…).因此,在這種情況下,它將向上舍入.
如果有人想知道為什么他們確實改變了算法:Java 7對于諸如`1234567890123.45949`之類的值做錯了.因此修復程序引入了一個新的bug ...解決方法是使用`nf.format(new BigDecimal(num))`來避免這兩個錯誤. (4認同)
@Peter Lawrey:`new BigDecimal(double)`和`BigDecimal.valueOf(double)`不一樣.后者將執行隱式的round-to-double操作,這將重新引入`1234567890123.45949`的雙舍入問題.但是,如果你真的意味著`1234567890123.4595`,`valueOf`將是更好的選擇.如果你想要安全起見,請使用`BigDecimal.valueOf(String)` (3認同)
+1表示已經為HALF_DOWN修復了它. (2認同)
總結
以上是生活随笔為你收集整理的java8 numberformat,NumberFormat舍入问题仅限Java 8的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2020年周记(3/50)
- 下一篇: 程序员偷偷深爱的 9 个不良编程习惯