JDK8 BigDecimal API-创建BigDecimal源码浅析三
第三篇
先介绍以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源码浅析三的更多相关文章
- ArrayList类源码浅析(三)
1.看一个示例 运行上述代码,抛出一个异常: 这是一个典型的并发修改异常,如果把上述代码中的125行注释,把126行打开,运行就能通过了: 原因: 1)因为在迭代的时候,使用的是Itr类的对象,在调用 ...
- 【深入浅出jQuery】源码浅析--整体架构
最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...
- Android开发之Theme、Style探索及源码浅析
1 背景 前段时间群里有伙伴问到了关于Android开发中Theme与Style的问题,当然,这类东西在网上随便一搜一大把模板,所以关于怎么用的问题我想这里也就不做太多的说明了,我们这里把重点放在理解 ...
- CountDownLatch源码浅析
Cmd Markdown链接 CountDownLatch源码浅析 参考好文: JDK1.8源码分析之CountDownLatch(五) Java并发之CountDownLatch源码分析 Count ...
- Bytom侧链Vapor源码浅析-节点出块过程
Bytom侧链Vapor源码浅析-节点出块过程 在这篇文章中,作者将从Vapor节点的创建开始,进而拓展讲解Vapor节点出块过程中所涉及的源码. 做为Vapor源码解析系列的第一篇,本文首先对Vap ...
- Phoenix创建索引源码过程
date: 2020-09-27 13:50:00 updated: 2020-09-28 16:30:00 Phoenix创建索引源码过程 org.apache.phoenix.index.Inde ...
- redux 源码浅析
redux 源码浅析 redux 版本号: "redux": "4.0.5" redux 作为一个十分常用的状态容器库, 大家都应该见识过, 他很小巧, 只有 ...
- 【深入浅出jQuery】源码浅析2--奇技淫巧
最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...
- Struts2源码浅析-ConfigurationProvider
ConfigurationProvider接口 主要完成struts配置文件 加载 注册过程 ConfigurationProvider接口定义 public interface Configurat ...
随机推荐
- Linux安装Tomcat-Nginx-FastDFS-Redis-Solr-集群——【第六集之基本命令使用】
学习命令的方法:linux中所有操作都是命令操作,可想而知命令有多少,更严重的是每个命令有很多参数,记命令容易,记参数就难了,所以建议: 自己准备一个博客,把通常用到的命令及其功能记载下来,用到的时候 ...
- Java设计模式之建造者模式(生成器模式)
建造者模式: 也叫生成器模式.用来隐藏复合对象的创建过程,他把复合对象的创建过程加以抽象,通过子类继承和重载的方式,动态地创建具有复合属性的对象. 总结一句就是封装一个对象的构造过程,并允许按步骤构造 ...
- CodeForces - 1013C C - Photo of The Sky 贪心
题目链接: https://vjudge.net/problem/1735276/origin 题目大意与思路: 题目的基本意思就是求一个矩形的最小面积. 这个可以用最大最小值, 将他们分为X和Y组. ...
- LOJ.2864.[IOI2018]排座位(线段树)
LOJ 洛谷 先令编号从\(1\)开始.我们要求\([1,i]\)这些数字能否构成一个矩形. 考虑能否用线段树维护,让每个叶子节点\(i\)表示前\(i\)个数能否构成矩形. 一种方法是维护前\(i\ ...
- numpy中的广播
目录 广播的引出 广播的原则 数组维度不同,后缘维度的轴长相符 数组维度相同,其中有个轴为1 参考: 广播的引出 numpy两个数组的相加.相减以及相乘都是对应元素之间的操作. import num ...
- vee-validate的使用
官网地址:http://vee-validate.logaretm.com/ 这是一个插件Vue.js可以验证输入字段,显示错误,在一个简单而强大的方法.学习vee-validate,首先可以去阅读官 ...
- 客户端无法加入域,报错:“无法与域‘xxx.com’的Active Directory域控制器(AD DC)链接” 请确保键入的域名正确
1.客户端能不能解析到域名? nslookup 一下域名看看解析到的IP的地址 2.客户端的DNS要指向DC 3.客户端的相关服务,workstation,TCP/IP NetBios Helper, ...
- POJ 1324 Holedox Moving (状压BFS)
POJ 1324 Holedox Moving (状压BFS) Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 18091 Acc ...
- snmp简单测试
一.环境搭建 搜索windows Server2003安装配置snmp 服务,按照提示来就行 二.利用 1.找出Coummunity Strings 利用于 auxiliary/scanner/snm ...
- 安装配置Greenplum
一.规划 1.服务器: 192.168.0.191 gpdb01 # master 192.168.0.192 gpdb02 # primary segment . ...