JDK8 BigDecimal API

Wesley13
• 阅读 767

第三篇

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

 1     public BigDecimal(BigInteger val) {// 根据BigInteger创建BigDecimal对象
 2         scale = 0;// BigInteger为整数因此有效小数位数为0
 3         intVal = val;
 4         intCompact = compactValFor(val);
 5     }
 6     
 7     public BigDecimal(BigInteger unscaledVal, int scale) {// 这个与上一个差不多但是指定了有效小数位数,但是最终的BigDecimal的数值为unscaledVal*10^-scale次方
 8         // Negative scales are now allowed
 9         this.intVal = unscaledVal;
10         this.intCompact = compactValFor(unscaledVal);
11         this.scale = scale;
12     }
13     
14     public BigDecimal(BigInteger val, MathContext mc) {// 该方法转发调用下面的构造器
15         this(val,0,mc);
16     }
17        
18     public BigDecimal(BigInteger unscaledVal, int scale, MathContext mc) {
19         long compactVal = compactValFor(unscaledVal);
20         int mcp = mc.precision;
21         int prec = 0;
22         if (mcp > 0) { // do rounding,根据MathContext中的有效位数进行舍去操作,具体解析见第一篇BigDecimal源码解析文章
23             int mode = mc.roundingMode.oldMode;
24             if (compactVal == INFLATED) {
25                 prec = bigDigitLength(unscaledVal);
26                 int drop = prec - mcp;
27                 while (drop > 0) {
28                     scale = checkScaleNonZero((long) scale - drop);
29                     unscaledVal = divideAndRoundByTenPow(unscaledVal, drop, mode);
30                     compactVal = compactValFor(unscaledVal);
31                     if (compactVal != INFLATED) {
32                         break;
33                     }
34                     prec = bigDigitLength(unscaledVal);
35                     drop = prec - mcp;
36                 }
37             }
38             if (compactVal != INFLATED) {
39                 prec = longDigitLength(compactVal);
40                 int drop = prec - mcp;     // drop can't be more than 18
41                 while (drop > 0) {
42                     scale = checkScaleNonZero((long) scale - drop);
43                     compactVal = divideAndRound(compactVal, LONG_TEN_POWERS_TABLE[drop], mode);
44                     prec = longDigitLength(compactVal);
45                     drop = prec - mcp;
46                 }
47                 unscaledVal = null;
48             }
49         }
50         this.intVal = unscaledVal;
51         this.intCompact = compactVal;
52         this.scale = scale;
53         this.precision = prec;// 若MathContext中的有效位数小于等于0,则BigDecimal中的有效位数置为0
54     }

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

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

long类型参数的构造器分析

 1     public BigDecimal(long val) {// 以long类型数值来创建BigDecimal对象,long类型为整数则有效小数位数为0
 2         this.intCompact = val;
 3         this.intVal = (val == INFLATED) ? INFLATED_BIGINT : null;// 若val的数值为long类型最小值需要特殊处理,因为此时的val有特殊含义(数值在long类型下溢出)
 4         this.scale = 0;
 5     }
 6 
 7     public BigDecimal(long val, MathContext mc) {// 该构造器在以long类型为参数的同时传入一个MathContext来限制有效位数
 8         int mcp = mc.precision;
 9         int mode = mc.roundingMode.oldMode;
10         int prec = 0;
11         int scale = 0;
12         BigInteger intVal = (val == INFLATED) ? INFLATED_BIGINT : null;
13         if (mcp > 0) { // do rounding,根据val的位数与MathContext的有效位数修正最终值的有效位数,即进行舍去操作,具体分析见第一篇BigDecimal源码分析文章
14             if (val == INFLATED) {// 若val为INFLATED即-2^63,该数位数为19,因此初始化有效位数为19
15                 prec = 19;
16                 int drop = prec - mcp;
17                 while (drop > 0) {
18                     scale = checkScaleNonZero((long) scale - drop);
19                     intVal = divideAndRoundByTenPow(intVal, drop, mode);
20                     val = compactValFor(intVal);
21                     if (val != INFLATED) {
22                         break;
23                     }
24                     prec = bigDigitLength(intVal);
25                     drop = prec - mcp;
26                 }
27             }
28             if (val != INFLATED) {
29                 prec = longDigitLength(val);
30                 int drop = prec - mcp;
31                 while (drop > 0) {
32                     scale = checkScaleNonZero((long) scale - drop);
33                     val = divideAndRound(val, LONG_TEN_POWERS_TABLE[drop], mc.roundingMode.oldMode);
34                     prec = longDigitLength(val);
35                     drop = prec - mcp;
36                 }
37                 intVal = null;
38             }
39         }
40         this.intVal = intVal;
41         this.intCompact = val;
42         this.scale = scale;
43         this.precision = prec;
44     }

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

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
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
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
java.math.BigDecimal类的用法
在java中提供了大数字的操作类,即java.math.BinInteger类和java.math.BigDecimal类。这两个类用于高精度计算,其中BigInteger类是针对大整数的处理类,而BigDecimal类则是针对大小数的处理类。下边我们介绍BigDecimal类:BigDecimal的实现利用到了BigInteger,不同的是Big
Wesley13 Wesley13
3年前
Java开发笔记(三十)大小数BigDecimal
前面介绍的BigInteger只能表达任意整数,但不能表达小数,要想表达任意小数,还需专门的大小数类型BigDecimal。如果说设计BigInteger的目的是替代int和long类型,那么设计BigDecimal的目的便是替代浮点型float和双精度型double了。正如它的兄弟BigInteger一般,BigDecimal不存在什么数值范围限制,无论是
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这