JDK8 BigDecimal API

第三篇

先介绍以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对象,几乎没有什么需要分析的,很简单大家可以自己看一看

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

java.math.BigDecimal类的用法

在java中提供了大数字的操作类,即java.math.BinInteger类和java.math.BigDecimal类。这两个类用于高精度计算,其中BigInteger类是针对大整数的处理类,而BigDecimal类则是针对大小数的处理类。下边我们介绍BigDecimal类:BigDecimal的实现利用到了BigInteger,不同的是Big