这节我们主要来说一说BigDecimal这个类,为啥要单独说这个类呢?因为后面学了数据库之后,我们会用到这个类。

一、认识BigDecimal

首先我们先百度百科一下(这个比较专业)

Java学习里程-----Java基础_26 BigDecimal类

因为我写博客的日期是4月4号凌晨,这个图片啥的都变灰了,原因是这个

Java学习里程-----Java基础_26 BigDecimal类

这里我也说一下, 很感谢国家,感谢这个社会,在疫情期间奋战在一线的工作人员,很感谢你们,谢谢。

“生如夏花般灿烂,死如秋叶之静美。”泰戈尔的话道出了生命的辉煌和壮丽。自古以来,赞颂生命的文人墨客数不胜数,每一个生命都是最珍贵最神圣的,因而我们应该学会敬畏生命。

哀悼完,我们继续来讲述BigDecimal这个类。

看百度百科中有这么一句话:“用来对超过16位有效位的数进行精确的运算。”

可以看出来啊,这个类还是很可以的啊,我之前项目就是用这个BigDecimal进行计算价格。

二、BigDecimal源码

打开API,地址:https://docs.oracle.com/javase/8/docs/api/

Java学习里程-----Java基础_26 BigDecimal类

可以看到继承关系,BigDecimal继承了Number,Number继承了Object。然后我们打开Eclipse,我们创建一个类,然后输入BigDecimal,注意是java.math包下面的!!!我们点进去看一下源码

Java学习里程-----Java基础_26 BigDecimal类

Java学习里程-----Java基础_26 BigDecimal类

... 不好意思,我没有放源码包,算了,不看了,我们从API看吧

我们主要来看方法

Java学习里程-----Java基础_26 BigDecimal类

它呢,给我们提供了很多方法,其中就有我们的加减乘除,我们来看一下

加法调用add,如下

Java学习里程-----Java基础_26 BigDecimal类

减法调用subtract

Java学习里程-----Java基础_26 BigDecimal类

乘法调用multiply

Java学习里程-----Java基础_26 BigDecimal类

除法调用divide

Java学习里程-----Java基础_26 BigDecimal类

我们发现,这个除法有很多重写的方法,这个我们会到时候说的。

三、BigDecimal的加减乘除等方法的使用

我们直接创建一个Test的类,我们来用用这个BigDecimal。

在使用之前,我们先定义两个数字,一个是5 一个是2

我们呢,选择这个构造函数进行定义

Java学习里程-----Java基础_26 BigDecimal类

Java学习里程-----Java基础_26 BigDecimal类

定义好之后,我们来进行计算

加法

首先计算number1 + number2,我们来使用一下add()这个方法。

Java学习里程-----Java基础_26 BigDecimal类

我们传入一个要加的值 number2

Java学习里程-----Java基础_26 BigDecimal类

输出一下

Java学习里程-----Java基础_26 BigDecimal类

当然呢,加法计算,谁在前谁在后无所谓啊,你也可以number2.add(number1); 计算结果都是7.

减法

减法计算我们调用的是subtract,我们来讲add修改成subtract

Java学习里程-----Java基础_26 BigDecimal类

我们运行,看一下结果

Java学习里程-----Java基础_26 BigDecimal类

也是OK的,但是,减法存在减数和被减数,所以number2.subtract(number1); 结果是 -3

Java学习里程-----Java基础_26 BigDecimal类

乘法

接下来是乘法,乘法我们用的是multiply,我们来算一下 number1 乘 number2的值

Java学习里程-----Java基础_26 BigDecimal类

Java学习里程-----Java基础_26 BigDecimal类

等于10,没有问题,当然,乘法和加法一样,不存在位置不一样得出的结果不一样,所以number2.multiply(number1);也是10

除法

除法我们用的是divide,这里我们要开始注意了,我们来计算number1 除 number2的值

Java学习里程-----Java基础_26 BigDecimal类

2.5,没有问题,结果没有错,如果我们将2改成3 呢,我们再来看一下

Java学习里程-----Java基础_26 BigDecimal类

报错了???,我们来解读一下错误日志,看看是啥错误

java.lang.ArithmeticException:  Non-terminating decimal expansion; no exact representable decimal result.

首先是这个Exception,这个异常是算术运算异常,具体的错误原因我们再来看一下

Java学习里程-----Java基础_26 BigDecimal类

说是结果没有办法表示,的确,5除3的确除不开,这怎么办呢?

我们来看一下divide的其他重载方法。

我翻译了一圈,我是看着描述都差不多。我直接告诉大家用那一个。

public BigDecimal divide(BigDecimal divisor,int scale,int roundingMode)

就这个,我来解释一下参数,divisor就是你要除的内个数字,scale就是你要保留几个小数,roundingMode就是要按照哪种方法进行舍入,这里呢,BigDecimal提供了8中规则我们来介绍一下

public final static int ROUND_UP =           0;

舍入远离零的舍入模式。

在丢弃非零部分之前始终增加数字(始终对非零舍弃部分前面的数字加1)。

注意,此舍入模式始终不会减少计算值的大小。

解释:拿到一串数字,好比是10.005这个数字,如果保留两位小数,而且按照这个规则,我们可以得到10.01,为啥呢,原本我们要保留两位,最后的结果应该是10.00,但是,我们使用了规则之后,我们不管0.00 后面是几,都会进一位数字给十分位的。

Java学习里程-----Java基础_26 BigDecimal类

Java学习里程-----Java基础_26 BigDecimal类

Java学习里程-----Java基础_26 BigDecimal类

public final static int ROUND_DOWN =         1;

接近零的舍入模式。

在丢弃某部分之前始终不增加数字(从不对舍弃部分前面的数字加1,即截短)。

注意,此舍入模式始终不会增加计算值的大小。

解释:就是,不管我们怎么保留,只保留到该保留的地方,剩下的直接舍去。我们再用10.001实验,保留两位数字,并且使用该模式,我们发现,不管是0.001 还是0.004,或者是0.009,我们最后都只能得到10.00。

public final static int ROUND_CEILING =      2;

接近正无穷大的舍入模式。

如果 BigDecimal 为正,则舍入行为与 ROUND_UP 相同;

如果为负,则舍入行为与 ROUND_DOWN 相同。

注意,此舍入模式始终不会减少计算值。

解释:这个就是结合上面内俩,看我们传入的是正数还是负数,这里我们直接测试。

Java学习里程-----Java基础_26 BigDecimal类

我们通过测试发现,这个会保留比传入数字大的,不管是正数还是负数。

public final static int ROUND_FLOOR =        3;

接近负无穷大的舍入模式。

如果 BigDecimal 为正,则舍入行为与 ROUND_DOWN 相同;

如果为负,则舍入行为与 ROUND_UP 相同。

注意,此舍入模式始终不会增加计算值。

解释:正好与上面的ROUND_CEILING 相反

Java学习里程-----Java基础_26 BigDecimal类

大家可以自己测试哦。

public final static int ROUND_HALF_UP =      4;

向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则为向上舍入的舍入模式。

如果舍弃部分 >= 0.5,则舍入行为与 ROUND_UP 相同;否则舍入行为与 ROUND_DOWN 相同。

注意,这是我们大多数人在小学时就学过的舍入模式(四舍五入)。

解释:这个就是四舍五入,没有啥多解释的,我直接上测试结果。

Java学习里程-----Java基础_26 BigDecimal类

Java学习里程-----Java基础_26 BigDecimal类

public final static int ROUND_HALF_DOWN =    5;

向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则为上舍入的舍入模式。

如果舍弃部分 > 0.5,则舍入行为与 ROUND_UP 相同;否则舍入行为与 ROUND_DOWN 相同(五舍六入)。

解释:这个就是五舍六入,小于或者等于5的时候,就舍弃掉,比5大就进位。看测试。

Java学习里程-----Java基础_26 BigDecimal类

Java学习里程-----Java基础_26 BigDecimal类

public final static int ROUND_HALF_EVEN =    6;

向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。

如果舍弃部分左边的数字为奇数,则舍入行为与 ROUND_HALF_UP 相同;

如果为偶数,则舍入行为与 ROUND_HALF_DOWN 相同。

注意,在重复进行一系列计算时,此舍入模式可以将累加错误减到最小。

此舍入模式也称为“银行家舍入法”,主要在美国使用。四舍六入,五分两种情况。

如果前一位为奇数,则入位,否则舍去。

解释:我们好比要保留两位小数,我们看第三位小数位的数字是多少,如果小于或者等于4,就舍弃掉,如果第三位小数位的数字等于或者大于6,那么就进一位。

如果,第三位小数位的数字是5,则需要看它前一位是奇数还是偶数,如果是奇数,就进位,如果是偶数,则舍去。我们来测试

Java学习里程-----Java基础_26 BigDecimal类

Java学习里程-----Java基础_26 BigDecimal类

Java学习里程-----Java基础_26 BigDecimal类

Java学习里程-----Java基础_26 BigDecimal类

Java学习里程-----Java基础_26 BigDecimal类

大家可以自己测试一下。

public final static int ROUND_UNNECESSARY =  7;

断言请求的操作具有精确的结果,因此不需要舍入。

如果对获得精确结果的操作指定此舍入模式,则抛出ArithmeticException。

解释:这个我是觉得没啥用,如果保留两位小数,但是我们要保留的小数有三位,好比10.001,这个一旦用了ROUND_UNNECESSARY这个规则,就报错,如果正好就两位,那么就没事,但是,我们本来就是两位小数,还保存两位小数,这不吃饱撑的吗。

到这里为止,除法就讲完了,具体用哪一种规则,需要看需求,由需求去定规则。

比较大小

我们呢,除去计算加减乘除之外,还可以比较大小,这里呢,我们也来使用一下。

我们调用compareTo()这个方法

Java学习里程-----Java基础_26 BigDecimal类

我们不难看出,返回的是一个int,我们来看看这个int会输出什么

Java学习里程-----Java基础_26 BigDecimal类

5和3比,输出了1

Java学习里程-----Java基础_26 BigDecimal类

3 和 5 比,输出了-1

Java学习里程-----Java基础_26 BigDecimal类

3 和 3比,输出了 0

这里我们可以知道,A和B比,如果A大,那么 compareTo 执行后的值是 1,如果是B大,则结果为-1,如果是结果是0,那么A和B相等。

 

好了,讲述到这里,我们BigDecimal就先告一段落了,大家要好好理解、记忆。

 

Java学习里程-----Java基础_26 BigDecimal类

ps:这是我个人公众号,希望大家可以关注一下,我近期推出了活动,大家可以积极参加一下,奖品丰厚哦。

如有疑问,加我个人QQ:2100363119

Java学习里程-----Java基础_26 BigDecimal类

相关文章: