java.text.NumberFormat 格式化数值 四舍五入问题, 求解

school104 2013-05-22 03:20:33
刚在网上看到的,看了下问题确实如此, 为什么 333.525 被四舍了 ,而不是五入呢 ?

public static void main(String[] args)
{
NumberFormat nf = NumberFormat.getInstance();
nf.setMinimumIntegerDigits(4);
nf.setMaximumFractionDigits(2);
System.out.println(nf.format(333.525));
System.out.println(nf.format(333.52500001));
}

输出:
0,333.52
0,333.53




...全文
1218 6 打赏 收藏 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
u_had_me_at_hello 2015-10-22
  • 打赏
  • 举报
回复
感觉不是数位的关系: NumberFormat percent = NumberFormat.getPercentInstance(); rate = percent.format(0.055); System.out.println( rate); rate = percent.format(0.065); System.out.println( rate); 一个结果是6%,第二个结果依然是6%。 然后我多试了几个数,发现进位后是偶数的,就五入,如果是奇数,就四舍。但是0.065后面再加以为,比如0.0651,答案又变成7%了。 楼主搞懂了吗?求解
school104 2013-05-22
  • 打赏
  • 举报
回复
引用 2 楼 flagiris 的回复:
默认的取舍模式应该就是那样吧,具体需要看源码。 不过只要你明确指定四舍五入的模式应该没有问题。。 NumberFormat nf = NumberFormat.getInstance(); nf.setRoundingMode(RoundingMode.HALF_UP); nf.setMinimumIntegerDigits(4); nf.setMaximumFractionDigits(2); System.out.println(nf.format(333.525)); System.out.println(nf.format(333.52500001));
看了下源码NumberFormat的RoundingMode决定着处理方式,默认为 ROUND_HALF_EVEN , 下面是几个参数的解释 : 1. ROUND_CEILING 如果BigDecimal是正的,则做ROUND_UP操作;如果为负,则做ROUND_DOWN操作。 2. ROUND_DOWN 从不在舍弃(即截断)的小数之前增加数字。 3. ROUND_FLOOR 如果BigDecimal为正,则作ROUND_UP;如果为负,则作ROUND_DOWN。 4. ROUND_HALF_DOWN 若舍弃部分>.5,则作ROUND_UP;否则,作ROUND_DOWN。 5. ROUND_HALF_EVEN 如果舍弃部分左边的数字为奇数,则作ROUND_HALF_UP;如果它为偶数,则作 ROUND_HALF_DOWN 。 6. ROUND_HALF_UP 若舍弃部分>=.5,则作ROUND_UP;否则,作ROUND_DOWN。 7. ROUND_UNNECESSARY 该“伪舍入模式”实际是指明所要求的操作必须是精确的,,因此不需要舍入操作。 8. ROUND_UP 总是在非0舍弃小数(即截断)之前增加数字。
school104 2013-05-22
  • 打赏
  • 举报
回复
引用 2 楼 flagiris 的回复:
默认的取舍模式应该就是那样吧,具体需要看源码。 不过只要你明确指定四舍五入的模式应该没有问题。。 NumberFormat nf = NumberFormat.getInstance(); nf.setRoundingMode(RoundingMode.HALF_UP); nf.setMinimumIntegerDigits(4); nf.setMaximumFractionDigits(2); System.out.println(nf.format(333.525)); System.out.println(nf.format(333.52500001));
NumberFormat的RoundingMode 默认为 ROUND_HALF_EVEN
跳蚤图 2013-05-22
  • 打赏
  • 举报
回复
这个看看源代码就清楚了 关键在if判断,第二种情况位数是11位,比2+3=5大,所以走进if判断里。 第一种情况没走进。
private final void round(int maximumDigits) {
        // Eliminate digits beyond maximum digits to be displayed.
        // Round up if appropriate.
        if (maximumDigits >= 0 && maximumDigits < count) {
            if (shouldRoundUp(maximumDigits)) {
                // Rounding up involved incrementing digits from LSD to MSD.
                // In most cases this is simple, but in a worst case situation
                // (9999..99) we have to adjust the decimalAt value.
                for (;;) {
                    --maximumDigits;
                    if (maximumDigits < 0) {
                        // We have all 9's, so we increment to a single digit
                        // of one and adjust the exponent.
                        digits[0] = '1';
                        ++decimalAt;
                        maximumDigits = 0; // Adjust the count
                        break;
                    }

                    ++digits[maximumDigits];
                    if (digits[maximumDigits] <= '9') break;
                    // digits[maximumDigits] = '0'; // Unnecessary since we'll truncate this
                }
                ++maximumDigits; // Increment for use as count
            }
            count = maximumDigits;

            // Eliminate trailing zeros.
            while (count > 1 && digits[count-1] == '0') {
                --count;
            }
        }
    }
菖蒲老先生 2013-05-22
  • 打赏
  • 举报
回复
默认的取舍模式应该就是那样吧,具体需要看源码。 不过只要你明确指定四舍五入的模式应该没有问题。。 NumberFormat nf = NumberFormat.getInstance(); nf.setRoundingMode(RoundingMode.HALF_UP); nf.setMinimumIntegerDigits(4); nf.setMaximumFractionDigits(2); System.out.println(nf.format(333.525)); System.out.println(nf.format(333.52500001));

62,620

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧