第三篇

先介绍以BigInteger为构造参数的构造器

     public BigDecimal(BigInteger val) {// 根据BigInteger创建BigDecimal对象
scale = 0;// BigInteger为整数因此有效小数位数为0
intVal = val;
intCompact = compactValFor(val);
} public BigDecimal(BigInteger unscaledVal, int scale) {// 这个与上一个差不多但是指定了有效小数位数,但是最终的BigDecimal的数值为unscaledVal*10^-scale次方
// Negative scales are now allowed
this.intVal = unscaledVal;
this.intCompact = compactValFor(unscaledVal);
this.scale = scale;
} public BigDecimal(BigInteger val, MathContext mc) {// 该方法转发调用下面的构造器
this(val,0,mc);
} public BigDecimal(BigInteger unscaledVal, int scale, MathContext mc) {
long compactVal = compactValFor(unscaledVal);
int mcp = mc.precision;
int prec = 0;
if (mcp > 0) { // do rounding,根据MathContext中的有效位数进行舍去操作,具体解析见第一篇BigDecimal源码解析文章
int mode = mc.roundingMode.oldMode;
if (compactVal == INFLATED) {
prec = bigDigitLength(unscaledVal);
int drop = prec - mcp;
while (drop > 0) {
scale = checkScaleNonZero((long) scale - drop);
unscaledVal = divideAndRoundByTenPow(unscaledVal, drop, mode);
compactVal = compactValFor(unscaledVal);
if (compactVal != INFLATED) {
break;
}
prec = bigDigitLength(unscaledVal);
drop = prec - mcp;
}
}
if (compactVal != INFLATED) {
prec = longDigitLength(compactVal);
int drop = prec - mcp; // drop can't be more than 18
while (drop > 0) {
scale = checkScaleNonZero((long) scale - drop);
compactVal = divideAndRound(compactVal, LONG_TEN_POWERS_TABLE[drop], mode);
prec = longDigitLength(compactVal);
drop = prec - mcp;
}
unscaledVal = null;
}
}
this.intVal = unscaledVal;
this.intCompact = compactVal;
this.scale = scale;
this.precision = prec;// 若MathContext中的有效位数小于等于0,则BigDecimal中的有效位数置为0
}

接下来介绍以int类型为构造参数的构造器

     public BigDecimal(int val) {// 以int数值来创建BigDecimal对象,int类型为整数则有效小数位数为0
this.intCompact = val;
this.scale = 0;
this.intVal = null;// 此时BigDecimal的数值在int类型的表数范围因此也在long类型的表数范围,所以intVal为null
} public BigDecimal(int val, MathContext mc) {// 该构造器在以int类型为参数的同时传入一个MathContext来限制有效位数
int mcp = mc.precision;
long compactVal = val;
int scale = 0;
int prec = 0;
if (mcp > 0) { // do rounding,根据val的位数与MathContext的有效位数修正最终值的有效位数,即进行舍去操作,具体分析见第一篇BigDecimal源码分析文章
prec = longDigitLength(compactVal);
int drop = prec - mcp; // drop can't be more than 18
while (drop > 0) {
scale = checkScaleNonZero((long) scale - drop);
compactVal = divideAndRound(compactVal, LONG_TEN_POWERS_TABLE[drop], mc.roundingMode.oldMode);
prec = longDigitLength(compactVal);
drop = prec - mcp;
}
}
this.intVal = null;
this.intCompact = compactVal;// BigDecimal对象表示数值的简洁值就是int类型参数val
this.scale = scale;
this.precision = prec;
}

long类型参数的构造器分析

     public BigDecimal(long val) {// 以long类型数值来创建BigDecimal对象,long类型为整数则有效小数位数为0
this.intCompact = val;
this.intVal = (val == INFLATED) ? INFLATED_BIGINT : null;// 若val的数值为long类型最小值需要特殊处理,因为此时的val有特殊含义(数值在long类型下溢出)
this.scale = 0;
} public BigDecimal(long val, MathContext mc) {// 该构造器在以long类型为参数的同时传入一个MathContext来限制有效位数
int mcp = mc.precision;
int mode = mc.roundingMode.oldMode;
int prec = 0;
int scale = 0;
BigInteger intVal = (val == INFLATED) ? INFLATED_BIGINT : null;
if (mcp > 0) { // do rounding,根据val的位数与MathContext的有效位数修正最终值的有效位数,即进行舍去操作,具体分析见第一篇BigDecimal源码分析文章
if (val == INFLATED) {// 若val为INFLATED即-2^63,该数位数为19,因此初始化有效位数为19
prec = 19;
int drop = prec - mcp;
while (drop > 0) {
scale = checkScaleNonZero((long) scale - drop);
intVal = divideAndRoundByTenPow(intVal, drop, mode);
val = compactValFor(intVal);
if (val != INFLATED) {
break;
}
prec = bigDigitLength(intVal);
drop = prec - mcp;
}
}
if (val != INFLATED) {
prec = longDigitLength(val);
int drop = prec - mcp;
while (drop > 0) {
scale = checkScaleNonZero((long) scale - drop);
val = divideAndRound(val, LONG_TEN_POWERS_TABLE[drop], mc.roundingMode.oldMode);
prec = longDigitLength(val);
drop = prec - mcp;
}
intVal = null;
}
}
this.intVal = intVal;
this.intCompact = val;
this.scale = scale;
this.precision = prec;
}

BigDecimal的原码接下来是一堆的静态方法用于创建BigDecimal对象,几乎没有什么需要分析的,很简单大家可以自己看一看

JDK8 BigDecimal API-创建BigDecimal源码浅析三的更多相关文章

  1. ArrayList类源码浅析(三)

    1.看一个示例 运行上述代码,抛出一个异常: 这是一个典型的并发修改异常,如果把上述代码中的125行注释,把126行打开,运行就能通过了: 原因: 1)因为在迭代的时候,使用的是Itr类的对象,在调用 ...

  2. 【深入浅出jQuery】源码浅析--整体架构

    最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...

  3. Android开发之Theme、Style探索及源码浅析

    1 背景 前段时间群里有伙伴问到了关于Android开发中Theme与Style的问题,当然,这类东西在网上随便一搜一大把模板,所以关于怎么用的问题我想这里也就不做太多的说明了,我们这里把重点放在理解 ...

  4. CountDownLatch源码浅析

    Cmd Markdown链接 CountDownLatch源码浅析 参考好文: JDK1.8源码分析之CountDownLatch(五) Java并发之CountDownLatch源码分析 Count ...

  5. Bytom侧链Vapor源码浅析-节点出块过程

    Bytom侧链Vapor源码浅析-节点出块过程 在这篇文章中,作者将从Vapor节点的创建开始,进而拓展讲解Vapor节点出块过程中所涉及的源码. 做为Vapor源码解析系列的第一篇,本文首先对Vap ...

  6. Phoenix创建索引源码过程

    date: 2020-09-27 13:50:00 updated: 2020-09-28 16:30:00 Phoenix创建索引源码过程 org.apache.phoenix.index.Inde ...

  7. redux 源码浅析

    redux 源码浅析 redux 版本号: "redux": "4.0.5" redux 作为一个十分常用的状态容器库, 大家都应该见识过, 他很小巧, 只有 ...

  8. 【深入浅出jQuery】源码浅析2--奇技淫巧

    最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...

  9. Struts2源码浅析-ConfigurationProvider

    ConfigurationProvider接口 主要完成struts配置文件 加载 注册过程 ConfigurationProvider接口定义 public interface Configurat ...

随机推荐

  1. Linux安装Tomcat-Nginx-FastDFS-Redis-Solr-集群——【第六集之基本命令使用】

    学习命令的方法:linux中所有操作都是命令操作,可想而知命令有多少,更严重的是每个命令有很多参数,记命令容易,记参数就难了,所以建议: 自己准备一个博客,把通常用到的命令及其功能记载下来,用到的时候 ...

  2. Java设计模式之建造者模式(生成器模式)

    建造者模式: 也叫生成器模式.用来隐藏复合对象的创建过程,他把复合对象的创建过程加以抽象,通过子类继承和重载的方式,动态地创建具有复合属性的对象. 总结一句就是封装一个对象的构造过程,并允许按步骤构造 ...

  3. CodeForces - 1013C C - Photo of The Sky 贪心

    题目链接: https://vjudge.net/problem/1735276/origin 题目大意与思路: 题目的基本意思就是求一个矩形的最小面积. 这个可以用最大最小值, 将他们分为X和Y组. ...

  4. LOJ.2864.[IOI2018]排座位(线段树)

    LOJ 洛谷 先令编号从\(1\)开始.我们要求\([1,i]\)这些数字能否构成一个矩形. 考虑能否用线段树维护,让每个叶子节点\(i\)表示前\(i\)个数能否构成矩形. 一种方法是维护前\(i\ ...

  5. numpy中的广播

    目录 广播的引出 广播的原则 数组维度不同,后缘维度的轴长相符 数组维度相同,其中有个轴为1 参考: 广播的引出  numpy两个数组的相加.相减以及相乘都是对应元素之间的操作. import num ...

  6. vee-validate的使用

    官网地址:http://vee-validate.logaretm.com/ 这是一个插件Vue.js可以验证输入字段,显示错误,在一个简单而强大的方法.学习vee-validate,首先可以去阅读官 ...

  7. 客户端无法加入域,报错:“无法与域‘xxx.com’的Active Directory域控制器(AD DC)链接” 请确保键入的域名正确

    1.客户端能不能解析到域名? nslookup 一下域名看看解析到的IP的地址 2.客户端的DNS要指向DC 3.客户端的相关服务,workstation,TCP/IP NetBios Helper, ...

  8. POJ 1324 Holedox Moving (状压BFS)

    POJ 1324 Holedox Moving (状压BFS) Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 18091 Acc ...

  9. snmp简单测试

    一.环境搭建 搜索windows Server2003安装配置snmp 服务,按照提示来就行 二.利用 1.找出Coummunity Strings 利用于 auxiliary/scanner/snm ...

  10. 安装配置Greenplum

    一.规划 1.服务器: 192.168.0.191   gpdb01        # master 192.168.0.192   gpdb02        # primary segment . ...