Non-terminating decimal expansion; no exact representable decimal result
翻译:无法终止小数点扩展; 没有确切的可表示的小数结果
出现的情形:
BigDecimal num1 = new BigDecimal("10");
BigDecimal num2 = new BigDecimal("3");
BigDecimal num3 = num1.divide(num2);
出现了无线循环小数。
可以使用devide重载方法BigDecimal.divide(BigDecimal divisor, int scale, RoundingMode roundingMode) ;
RoundingMode源码解析:
public enum RoundingMode { /** * Rounding mode to round away from zero. Always increments the * digit prior to a non-zero discarded fraction. Note that this * rounding mode never decreases the magnitude of the calculated * value. * * 远离0的舍入模式。总是在非零的小数前增加数值。请注意,该舍入模式不会减小计算值的大小。 * *<p>Example: *<table border> *<tr valign=top><th>Input Number</th> * <th>Input rounded to one digit<br> with {@code UP} rounding *<tr align=right><td>5.5</td> <td>6</td> *<tr align=right><td>2.5</td> <td>3</td> *<tr align=right><td>1.6</td> <td>2</td> *<tr align=right><td>1.1</td> <td>2</td> *<tr align=right><td>1.0</td> <td>1</td> *<tr align=right><td>-1.0</td> <td>-1</td> *<tr align=right><td>-1.1</td> <td>-2</td> *<tr align=right><td>-1.6</td> <td>-2</td> *<tr align=right><td>-2.5</td> <td>-3</td> *<tr align=right><td>-5.5</td> <td>-6</td> *</table> * * 举个栗子: * 输入一个数字:5.5 2.5 1.6 1.1 1.0 -1.0 -1.1 -1.6 -2.5 -5.5 * 舍入后的数字:6 3 2 2 1 -1 -2 -2 -3 -6 */ UP(BigDecimal.ROUND_UP), /** * Rounding mode to round towards zero. Never increments the digit * prior to a discarded fraction (i.e., truncates). Note that this * rounding mode never increases the magnitude of the calculated value. * * 靠近0的舍入模式。在放弃的小数之前不递增数值(即截断)。请注意,舍入模式不会增加计算值的大小。 * *<p>Example: *<table border> *<tr valign=top><th>Input Number</th> * <th>Input rounded to one digit<br> with {@code DOWN} rounding *<tr align=right><td>5.5</td> <td>5</td> *<tr align=right><td>2.5</td> <td>2</td> *<tr align=right><td>1.6</td> <td>1</td> *<tr align=right><td>1.1</td> <td>1</td> *<tr align=right><td>1.0</td> <td>1</td> *<tr align=right><td>-1.0</td> <td>-1</td> *<tr align=right><td>-1.1</td> <td>-1</td> *<tr align=right><td>-1.6</td> <td>-1</td> *<tr align=right><td>-2.5</td> <td>-2</td> *<tr align=right><td>-5.5</td> <td>-5</td> *</table> * * 举个栗子: * 输入一个数字:5.5 2.5 1.6 1.1 1.0 -1.0 -1.1 -1.6 -2.5 -5.5 * 舍入后的数字:5 2 1 1 1 -1 -1 -1 -2 -5 */ DOWN(BigDecimal.ROUND_DOWN), /** * Rounding mode to round towards positive infinity. If the * result is positive, behaves as for {@code RoundingMode.UP}; * if negative, behaves as for {@code RoundingMode.DOWN}. Note * that this rounding mode never decreases the calculated value. * * 向正无穷大舍入。如果结果是正数,执行RoundingMode.UP;如果结果是负数,执行RoundingMode.DOWN。 * 请注意,这个舍入模式决不会减少计算值。 * *<p>Example: *<table border> *<tr valign=top><th>Input Number</th> * <th>Input rounded to one digit<br> with {@code CEILING} rounding *<tr align=right><td>5.5</td> <td>6</td> *<tr align=right><td>2.5</td> <td>3</td> *<tr align=right><td>1.6</td> <td>2</td> *<tr align=right><td>1.1</td> <td>2</td> *<tr align=right><td>1.0</td> <td>1</td> *<tr align=right><td>-1.0</td> <td>-1</td> *<tr align=right><td>-1.1</td> <td>-1</td> *<tr align=right><td>-1.6</td> <td>-1</td> *<tr align=right><td>-2.5</td> <td>-2</td> *<tr align=right><td>-5.5</td> <td>-5</td> *</table> * * 举个栗子: * 输入一个数字:5.5 2.5 1.6 1.1 1.0 -1.0 -1.1 -1.6 -2.5 -5.5 * 舍入后的数字:6 3 2 2 1 -1 -1 -1 -2 -5 */ CEILING(BigDecimal.ROUND_CEILING), /** * Rounding mode to round towards negative infinity. If the * result is positive, behave as for {@code RoundingMode.DOWN}; * if negative, behave as for {@code RoundingMode.UP}. Note that * this rounding mode never increases the calculated value. * * 向负无穷大舍入。如果结果是正数,执行RoundingMode.DOWN;如果结果是负数,执行RoundingMode.UP。 * *<p>Example: *<table border> *<tr valign=top><th>Input Number</th> * <th>Input rounded to one digit<br> with {@code FLOOR} rounding *<tr align=right><td>5.5</td> <td>5</td> *<tr align=right><td>2.5</td> <td>2</td> *<tr align=right><td>1.6</td> <td>1</td> *<tr align=right><td>1.1</td> <td>1</td> *<tr align=right><td>1.0</td> <td>1</td> *<tr align=right><td>-1.0</td> <td>-1</td> *<tr align=right><td>-1.1</td> <td>-2</td> *<tr align=right><td>-1.6</td> <td>-2</td> *<tr align=right><td>-2.5</td> <td>-3</td> *<tr align=right><td>-5.5</td> <td>-6</td> *</table> * * 举个栗子: * 输入一个数字:5.5 2.5 1.6 1.1 1.0 -1.0 -1.1 -1.6 -2.5 -5.5 * 舍入后的数字:5 2 1 1 1 -1 -2 -2 -3 -6 */ FLOOR(BigDecimal.ROUND_FLOOR), /** * Rounding mode to round towards {@literal "nearest neighbor"} * unless both neighbors are equidistant, in which case round up. * Behaves as for {@code RoundingMode.UP} if the discarded * fraction is ≥ 0.5; otherwise, behaves as for * {@code RoundingMode.DOWN}. Note that this is the rounding * mode commonly taught at school. * * 向最邻近的地方舍入。除非离左右两边的的数值是等距的,那么就是用ROUND_UP模式。 * 如果舍弃的小数部分大于等于0.5,执行RoundingMode.UP,否则执行RoundingMode.DOWN。 * 请注意,这是学校常用的四舍五入舍入模式。 * *<p>Example: *<table border> *<tr valign=top><th>Input Number</th> * <th>Input rounded to one digit<br> with {@code HALF_UP} rounding *<tr align=right><td>5.5</td> <td>6</td> *<tr align=right><td>2.5</td> <td>3</td> *<tr align=right><td>1.6</td> <td>2</td> *<tr align=right><td>1.1</td> <td>1</td> *<tr align=right><td>1.0</td> <td>1</td> *<tr align=right><td>-1.0</td> <td>-1</td> *<tr align=right><td>-1.1</td> <td>-1</td> *<tr align=right><td>-1.6</td> <td>-2</td> *<tr align=right><td>-2.5</td> <td>-3</td> *<tr align=right><td>-5.5</td> <td>-6</td> *</table> * * 举个栗子: * 输入一个数字:5.5 2.5 1.6 1.1 1.0 -1.0 -1.1 -1.6 -2.5 -5.5 * 舍入后的数字:6 3 2 1 1 -1 -1 -2 -3 -6 */ HALF_UP(BigDecimal.ROUND_HALF_UP), /** * Rounding mode to round towards {@literal "nearest neighbor"} * unless both neighbors are equidistant, in which case round * down. Behaves as for {@code RoundingMode.UP} if the discarded * fraction is > 0.5; otherwise, behaves as for * {@code RoundingMode.DOWN}. * * 向最邻近的地方舍入。除非离左右两边的的数值是等距的,那么就是用ROUND_DOWN模式。 * 如果舍弃的小数部分大于0.5,执行RoundingMode.UP,否则执行RoundingMode.DOWN。 * *<p>Example: *<table border> *<tr valign=top><th>Input Number</th> * <th>Input rounded to one digit<br> with {@code HALF_DOWN} rounding *<tr align=right><td>5.5</td> <td>5</td> *<tr align=right><td>2.5</td> <td>2</td> *<tr align=right><td>1.6</td> <td>2</td> *<tr align=right><td>1.1</td> <td>1</td> *<tr align=right><td>1.0</td> <td>1</td> *<tr align=right><td>-1.0</td> <td>-1</td> *<tr align=right><td>-1.1</td> <td>-1</td> *<tr align=right><td>-1.6</td> <td>-2</td> *<tr align=right><td>-2.5</td> <td>-2</td> *<tr align=right><td>-5.5</td> <td>-5</td> *</table> * * 举个栗子: * 输入一个数字:5.5 2.5 1.6 1.1 1.0 -1.0 -1.1 -1.6 -2.5 -5.5 * 舍入后的数字:5 2 2 1 1 -1 -1 -2 -2 -5 */ HALF_DOWN(BigDecimal.ROUND_HALF_DOWN), /** * Rounding mode to round towards the {@literal "nearest neighbor"} * unless both neighbors are equidistant, in which case, round * towards the even neighbor. Behaves as for * {@code RoundingMode.HALF_UP} if the digit to the left of the * discarded fraction is odd; behaves as for * {@code RoundingMode.HALF_DOWN} if it's even. Note that this * is the rounding mode that statistically minimizes cumulative * error when applied repeatedly over a sequence of calculations. * It is sometimes known as {@literal "Banker's rounding,"} and is * chiefly used in the USA. This rounding mode is analogous to * the rounding policy used for {@code float} and {@code double} * arithmetic in Java. * * 向最邻近的地方舍入。除非离左右两边的的数值是等距的,那么就向最邻近的偶数舍入。 * 如果舍弃部分左边的数字是奇数,执行RoundingMode.HALF_UP。如果是偶数,执行RoundingMode.HALF_DOWN。 * 请注意,这是一个舍入模式,当在一系列计算中重复应用时,可以统计学上最小化累积误差。 * 它有时被称为"银行家四舍五入",主要用于美国。 * 这种舍入模式类似于Java中用于float和double算术的舍入策略。 * *<p>Example: *<table border> *<tr valign=top><th>Input Number</th> * <th>Input rounded to one digit<br> with {@code HALF_EVEN} rounding *<tr align=right><td>5.5</td> <td>6</td> *<tr align=right><td>2.5</td> <td>2</td> *<tr align=right><td>1.6</td> <td>2</td> *<tr align=right><td>1.1</td> <td>1</td> *<tr align=right><td>1.0</td> <td>1</td> *<tr align=right><td>-1.0</td> <td>-1</td> *<tr align=right><td>-1.1</td> <td>-1</td> *<tr align=right><td>-1.6</td> <td>-2</td> *<tr align=right><td>-2.5</td> <td>-2</td> *<tr align=right><td>-5.5</td> <td>-6</td> *</table> * * 举个栗子: * 输入一个数字:5.5 2.5 1.6 1.1 1.0 -1.0 -1.1 -1.6 -2.5 -5.5 * 舍入后的数字:6 2 2 1 1 -1 -1 -2 -2 -6 */ HALF_EVEN(BigDecimal.ROUND_HALF_EVEN), /** * Rounding mode to assert that the requested operation has an exact * result, hence no rounding is necessary. If this rounding mode is * specified on an operation that yields an inexact result, an * {@code ArithmeticException} is thrown. * * 舍入模式来断言所请求的操作具有确切的结果,因此不需要舍入。 * 如果在产生不精确结果的操作上指定了舍入模式,则抛出ArithmeticException。 * *<p>Example: *<table border> *<tr valign=top><th>Input Number</th> * <th>Input rounded to one digit<br> with {@code UNNECESSARY} rounding *<tr align=right><td>5.5</td> <td>throw {@code ArithmeticException}</td> *<tr align=right><td>2.5</td> <td>throw {@code ArithmeticException}</td> *<tr align=right><td>1.6</td> <td>throw {@code ArithmeticException}</td> *<tr align=right><td>1.1</td> <td>throw {@code ArithmeticException}</td> *<tr align=right><td>1.0</td> <td>1</td> *<tr align=right><td>-1.0</td> <td>-1</td> *<tr align=right><td>-1.1</td> <td>throw {@code ArithmeticException}</td> *<tr align=right><td>-1.6</td> <td>throw {@code ArithmeticException}</td> *<tr align=right><td>-2.5</td> <td>throw {@code ArithmeticException}</td> *<tr align=right><td>-5.5</td> <td>throw {@code ArithmeticException}</td> *</table> * * 举个栗子: * 输入一个数字:5.5 2.5 1.6 1.1 1.0 -1.0 -1.1 -1.6 -2.5 -5.5 * 舍入后的数字:异常 异常 异常 异常 1 -1 异常 异常 异常 异常 */ UNNECESSARY(BigDecimal.ROUND_UNNECESSARY); // Corresponding BigDecimal rounding constant final int oldMode; /** * Constructor * * @param oldMode The {@code BigDecimal} constant corresponding to * this mode */ private RoundingMode(int oldMode) { this.oldMode = oldMode; } /** * Returns the {@code RoundingMode} object corresponding to a * legacy integer rounding mode constant in {@link BigDecimal}. * * 返回BigDecimal中对应于传统整数舍入模式常量的RoundingMode对象。 * * @param rm legacy integer rounding mode to convert * @return {@code RoundingMode} corresponding to the given integer. * @throws IllegalArgumentException integer is out of range */ public static RoundingMode valueOf(int rm) { switch(rm) { case BigDecimal.ROUND_UP: return UP; case BigDecimal.ROUND_DOWN: return DOWN; case BigDecimal.ROUND_CEILING: return CEILING; case BigDecimal.ROUND_FLOOR: return FLOOR; case BigDecimal.ROUND_HALF_UP: return HALF_UP; case BigDecimal.ROUND_HALF_DOWN: return HALF_DOWN; case BigDecimal.ROUND_HALF_EVEN: return HALF_EVEN; case BigDecimal.ROUND_UNNECESSARY: return UNNECESSARY; default: throw new IllegalArgumentException("argument out of range"); } } }