【java笔记】java中用于小数进位的BigDecimal.setScale方法

BigDecimal.setScale主要用于对BigDecimal数据小数点后的位数进行进位、舍位、截断等操作。其进位方式主要有以下8种,依次分别对应着数字0~7,即写它们和写它们对应的数字是等价的。

  • ROUND_UP:小数点后指定位之后的数无论多大,都往高位进一
  • ROUND_DOWN:小数点后指定位之后的数无论多大,全部舍弃
  • ROUND_CEILING:如果是正数,相当于ROUND_UP,如果是负数,相当于ROUND_DOWN
  • ROUND_FLOOR:和ROUND_CEILING正好相反,如果是正数,相当于ROUND_DOWN,如果是负数,相当于ROUND_UP
  • ROUND_HALF_UP:若指定位数后若>=0.5,则进位,反之舍弃。
    • 如3.0499,小数点后1位后面为499,是<0.5的,所以不进位,变为3.0
    • 而3.0500,小数点后1位后面为500,是>=0.5的,所以要进位,变为3.1
  • ROUND_HALF_DOWN:若指定位数后若>0.5,则进位,反之舍弃。
    • 如3.0501,小数点后1位后面为501,是>0.5的,所以要进位,变为3.1
    • 而3.0500,小数点后1位后面为500,是=0.5的,所以不进位,变为3.0
  • ROUND_HALF_EVEN:若指定位为偶数,则做ROUND_HALF_DOWN,反之做ROUND_HALF_UP
  • ROUND_UNNECESSARY:若指定的位数>=小数位数,则抛异常java.lang.ArithmeticException: Rounding necessary
    空讲理论无益,直接看下面的例子:
package ecnu.cn;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

public class BigDecimalTest {

    public static void getScale(BigDecimal num, Integer type) {
        for (int i = 0; i < 10; i++) {
            try {
                System.out.print("i: " + i + "  ");
                System.out.println(num.setScale(i, type));
            } catch (Exception e){
                e.printStackTrace();
            }
        }
        System.out.println();
        BigDecimal negate = num.negate();
        for (int i = 0; i < 10; i++) {
            try{
                System.out.print("i: " + i + "  ");
                System.out.println(negate.setScale(i, type));
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        System.out.println("\n");
    }

    public static void main(String[] args) {
        // 建议使用字符串形式定义,这样不会损失精度
        BigDecimal num = new BigDecimal("3.123456789");

        List<Integer> lst = new ArrayList<>();
        // ROUND_UP:小数点后指定位之后的数无论多大,都往高位进一
        lst.add(BigDecimal.ROUND_UP);
        // ROUND_DOWN:小数点后指定位之后的数无论多大,全部舍弃
        lst.add(BigDecimal.ROUND_DOWN);
        // ROUND_CEILING:如果是正数,相当于ROUND_UP,如果是负数,相当于ROUND_DOWN
        lst.add(BigDecimal.ROUND_CEILING);
        // ROUND_FLOOR:和ROUND_CEILING正好相反,如果是正数,相当于ROUND_DOWN,如果是负数,相当于ROUND_UP
        lst.add(BigDecimal.ROUND_FLOOR);
        /* ROUND_HALF_UP:若指定位数后若>=0.5,则进位,反之舍弃。
            如3.0499,小数点后1位后面为499,是<0.5的,所以不进位,变为3.0
            而3.0500,小数点后1位后面为500,是>=0.5的,所以要进位,变为3.1
         */
        lst.add(BigDecimal.ROUND_HALF_UP);
        /* ROUND_HALF_DOWN:若指定位数后若>0.5,则进位,反之舍弃。
            如3.0501,小数点后1位后面为501,是>0.5的,所以要进位,变为3.1
            而3.0500,小数点后1位后面为500,是=0.5的,所以不进位,变为3.0
         */
        lst.add(BigDecimal.ROUND_HALF_DOWN);
        // ROUND_HALF_EVEN:若指定位为偶数,则做ROUND_HALF_DOWN,反之做ROUND_HALF_UP
        lst.add(BigDecimal.ROUND_HALF_EVEN);
        // ROUND_UNNECESSARY:若指定的位数>=小数位数,则抛异常java.lang.ArithmeticException: Rounding necessary
        // 在下面的例子中,由于num小数点后有9位,所以当i>=9时就会抛异常,而i<9时无输出。
        lst.add(BigDecimal.ROUND_UNNECESSARY);

        String[] name = new String[] {"ROUND_UP", "ROUND_DOWN", "ROUND_CEILING", "ROUND_FLOOR", "ROUND_HALF_UP",
            "ROUND_HALF_DOWN", "ROUND_HALF_EVEN", "ROUND_UNNECESSARY"};

        for (int i = 0; i < lst.size(); i++) {
            System.out.println(name[i] + ":");
            getScale(num, lst.get(i));
        }
    }
}

其输出为:

ROUND_UP:
i: 0  4
i: 1  3.2
i: 2  3.13
i: 3  3.124
i: 4  3.1235
i: 5  3.12346
i: 6  3.123457
i: 7  3.1234568
i: 8  3.12345679
i: 9  3.123456789

i: 0  -4
i: 1  -3.2
i: 2  -3.13
i: 3  -3.124
i: 4  -3.1235
i: 5  -3.12346
i: 6  -3.123457
i: 7  -3.1234568
i: 8  -3.12345679
i: 9  -3.123456789


ROUND_DOWN:
i: 0  3
i: 1  3.1
i: 2  3.12
i: 3  3.123
i: 4  3.1234
i: 5  3.12345
i: 6  3.123456
i: 7  3.1234567
i: 8  3.12345678
i: 9  3.123456789

i: 0  -3
i: 1  -3.1
i: 2  -3.12
i: 3  -3.123
i: 4  -3.1234
i: 5  -3.12345
i: 6  -3.123456
i: 7  -3.1234567
i: 8  -3.12345678
i: 9  -3.123456789


ROUND_CEILING:
i: 0  4
i: 1  3.2
i: 2  3.13
i: 3  3.124
i: 4  3.1235
i: 5  3.12346
i: 6  3.123457
i: 7  3.1234568
i: 8  3.12345679
i: 9  3.123456789

i: 0  -3
i: 1  -3.1
i: 2  -3.12
i: 3  -3.123
i: 4  -3.1234
i: 5  -3.12345
i: 6  -3.123456
i: 7  -3.1234567
i: 8  -3.12345678
i: 9  -3.123456789


ROUND_FLOOR:
i: 0  3
i: 1  3.1
i: 2  3.12
i: 3  3.123
i: 4  3.1234
i: 5  3.12345
i: 6  3.123456
i: 7  3.1234567
i: 8  3.12345678
i: 9  3.123456789

i: 0  -4
i: 1  -3.2
i: 2  -3.13
i: 3  -3.124
i: 4  -3.1235
i: 5  -3.12346
i: 6  -3.123457
i: 7  -3.1234568
i: 8  -3.12345679
i: 9  -3.123456789


ROUND_HALF_UP:
i: 0  3
i: 1  3.1
i: 2  3.12
i: 3  3.123
i: 4  3.1235
i: 5  3.12346
i: 6  3.123457
i: 7  3.1234568
i: 8  3.12345679
i: 9  3.123456789

i: 0  -3
i: 1  -3.1
i: 2  -3.12
i: 3  -3.123
i: 4  -3.1235
i: 5  -3.12346
i: 6  -3.123457
i: 7  -3.1234568
i: 8  -3.12345679
i: 9  -3.123456789


ROUND_HALF_DOWN:
i: 0  3
i: 1  3.1
i: 2  3.12
i: 3  3.123
i: 4  3.1235
i: 5  3.12346
i: 6  3.123457
i: 7  3.1234568
i: 8  3.12345679
i: 9  3.123456789

i: 0  -3
i: 1  -3.1
i: 2  -3.12
i: 3  -3.123
i: 4  -3.1235
i: 5  -3.12346
i: 6  -3.123457
i: 7  -3.1234568
i: 8  -3.12345679
i: 9  -3.123456789


ROUND_HALF_EVEN:
i: 0  3
i: 1  3.1
i: 2  3.12
i: 3  3.123
i: 4  3.1235
i: 5  3.12346
i: 6  3.123457
i: 7  3.1234568
i: 8  3.12345679
i: 9  3.123456789

i: 0  -3
i: 1  -3.1
i: 2  -3.12
i: 3  -3.123
i: 4  -3.1235
i: 5  -3.12346
i: 6  -3.123457
i: 7  -3.1234568
i: 8  -3.12345679
i: 9  -3.123456789


ROUND_UNNECESSARY:
i: 0  i: 1  i: 2  i: 3  i: 4  i: 5  i: 6  i: 7  i: 8  i: 9  3.123456789

i: 0  i: 1  i: 2  i: 3  i: 4  i: 5  i: 6  i: 7  i: 8  i: 9  -3.123456789


java.lang.ArithmeticException: Rounding necessary
	at java.math.BigDecimal.commonNeedIncrement(BigDecimal.java:4179)
	at java.math.BigDecimal.needIncrement(BigDecimal.java:4235)
	at java.math.BigDecimal.divideAndRound(BigDecimal.java:4143)
	at java.math.BigDecimal.setScale(BigDecimal.java:2455)
	at ecnu.cn.BigDecimalTest.getScale(BigDecimalTest.java:13)
	at ecnu.cn.BigDecimalTest.main(BigDecimalTest.java:65)

...
  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值