第三篇
先介绍以BigInteger为构造参数的构造器
1 1 public BigDecimal(BigInteger val) {// 根据BigInteger创建BigDecimal对象 2 2 scale = 0;// BigInteger为整数因此有效小数位数为0 3 3 intVal = val; 4 4 intCompact = compactValFor(val); 5 5 } 6 6 7 7 public BigDecimal(BigInteger unscaledVal, int scale) {// 这个与上一个差不多但是指定了有效小数位数,但是最终的BigDecimal的数值为unscaledVal*10^-scale次方 8 8 // Negative scales are now allowed 9 9 this.intVal = unscaledVal; 1010 this.intCompact = compactValFor(unscaledVal); 1111 this.scale = scale; 1212 } 1313 1414 public BigDecimal(BigInteger val, MathContext mc) {// 该方法转发调用下面的构造器 1515 this(val,0,mc); 1616 } 1717 1818 public BigDecimal(BigInteger unscaledVal, int scale, MathContext mc) { 1919 long compactVal = compactValFor(unscaledVal); 2020 int mcp = mc.precision; 2121 int prec = 0; 2222 if (mcp > 0) { // do rounding,根据MathContext中的有效位数进行舍去操作,具体解析见第一篇BigDecimal源码解析文章 2323 int mode = mc.roundingMode.oldMode; 2424 if (compactVal == INFLATED) { 2525 prec = bigDigitLength(unscaledVal); 2626 int drop = prec - mcp; 2727 while (drop > 0) { 2828 scale = checkScaleNonZero((long) scale - drop); 2929 unscaledVal = divideAndRoundByTenPow(unscaledVal, drop, mode); 3030 compactVal = compactValFor(unscaledVal); 3131 if (compactVal != INFLATED) { 3232 break; 3333 } 3434 prec = bigDigitLength(unscaledVal); 3535 drop = prec - mcp; 3636 } 3737 } 3838 if (compactVal != INFLATED) { 3939 prec = longDigitLength(compactVal); 4040 int drop = prec - mcp; // drop can't be more than 18 4141 while (drop > 0) { 4242 scale = checkScaleNonZero((long) scale - drop); 4343 compactVal = divideAndRound(compactVal, LONG_TEN_POWERS_TABLE[drop], mode); 4444 prec = longDigitLength(compactVal); 4545 drop = prec - mcp; 4646 } 4747 unscaledVal = null; 4848 } 4949 } 5050 this.intVal = unscaledVal; 5151 this.intCompact = compactVal; 5252 this.scale = scale; 5353 this.precision = prec;// 若MathContext中的有效位数小于等于0,则BigDecimal中的有效位数置为0 5454 }
接下来介绍以int类型为构造参数的构造器
1 1 public BigDecimal(int val) {// 以int数值来创建BigDecimal对象,int类型为整数则有效小数位数为0 2 2 this.intCompact = val; 3 3 this.scale = 0; 4 4 this.intVal = null;// 此时BigDecimal的数值在int类型的表数范围因此也在long类型的表数范围,所以intVal为null 5 5 } 6 6 7 7 public BigDecimal(int val, MathContext mc) {// 该构造器在以int类型为参数的同时传入一个MathContext来限制有效位数 8 8 int mcp = mc.precision; 9 9 long compactVal = val; 1010 int scale = 0; 1111 int prec = 0; 1212 if (mcp > 0) { // do rounding,根据val的位数与MathContext的有效位数修正最终值的有效位数,即进行舍去操作,具体分析见第一篇BigDecimal源码分析文章 1313 prec = longDigitLength(compactVal); 1414 int drop = prec - mcp; // drop can't be more than 18 1515 while (drop > 0) { 1616 scale = checkScaleNonZero((long) scale - drop); 1717 compactVal = divideAndRound(compactVal, LONG_TEN_POWERS_TABLE[drop], mc.roundingMode.oldMode); 1818 prec = longDigitLength(compactVal); 1919 drop = prec - mcp; 2020 } 2121 } 2222 this.intVal = null; 2323 this.intCompact = compactVal;// BigDecimal对象表示数值的简洁值就是int类型参数val 2424 this.scale = scale; 2525 this.precision = prec; 2626 }
long类型参数的构造器分析
1 1 public BigDecimal(long val) {// 以long类型数值来创建BigDecimal对象,long类型为整数则有效小数位数为0 2 2 this.intCompact = val; 3 3 this.intVal = (val == INFLATED) ? INFLATED_BIGINT : null;// 若val的数值为long类型最小值需要特殊处理,因为此时的val有特殊含义(数值在long类型下溢出) 4 4 this.scale = 0; 5 5 } 6 6 7 7 public BigDecimal(long val, MathContext mc) {// 该构造器在以long类型为参数的同时传入一个MathContext来限制有效位数 8 8 int mcp = mc.precision; 9 9 int mode = mc.roundingMode.oldMode; 1010 int prec = 0; 1111 int scale = 0; 1212 BigInteger intVal = (val == INFLATED) ? INFLATED_BIGINT : null; 1313 if (mcp > 0) { // do rounding,根据val的位数与MathContext的有效位数修正最终值的有效位数,即进行舍去操作,具体分析见第一篇BigDecimal源码分析文章 1414 if (val == INFLATED) {// 若val为INFLATED即-2^63,该数位数为19,因此初始化有效位数为19 1515 prec = 19; 1616 int drop = prec - mcp; 1717 while (drop > 0) { 1818 scale = checkScaleNonZero((long) scale - drop); 1919 intVal = divideAndRoundByTenPow(intVal, drop, mode); 2020 val = compactValFor(intVal); 2121 if (val != INFLATED) { 2222 break; 2323 } 2424 prec = bigDigitLength(intVal); 2525 drop = prec - mcp; 2626 } 2727 } 2828 if (val != INFLATED) { 2929 prec = longDigitLength(val); 3030 int drop = prec - mcp; 3131 while (drop > 0) { 3232 scale = checkScaleNonZero((long) scale - drop); 3333 val = divideAndRound(val, LONG_TEN_POWERS_TABLE[drop], mc.roundingMode.oldMode); 3434 prec = longDigitLength(val); 3535 drop = prec - mcp; 3636 } 3737 intVal = null; 3838 } 3939 } 4040 this.intVal = intVal; 4141 this.intCompact = val; 4242 this.scale = scale; 4343 this.precision = prec; 4444 }
BigDecimal的原码接下来是一堆的静态方法用于创建BigDecimal对象,几乎没有什么需要分析的,很简单大家可以自己看一看