bigdecimal不保留小数_深入理解 BigDecimal
关注公众号:小李不秃
什么是 BigDecimal
BigDecimal 可以表示一个任意大小且精度完全准确的浮点数。
为什么用 BigDecimal 而不用 double
Talk is cheap, Show me the Code.
例 1:
double
运行结果
Double:
从运行结果可以得出,当我们要做精确的小数操作运算时,就需要用到 BigDecimal。那下面做一下除法运算,看看结果:
例 2:
double
运行结果
Double:
当结果除不进,并且没有设置进位的状态值,那就会抛出异常。正确的操作如下:
System
运行结果
Double:
总结:当我们在精度要求非常高的时候,需要进行精确的计算,比如:货币,那我们就需要采用 java.math.BigDecimal 类来进行精确计算。
加减乘除
public
运行结果:
a
常用方法
保留两位小数
public
四舍五入
- ROUND_UP
舍入远离零的舍入模式。
在丢弃非零部分之前始终增加数字(始终对非零舍弃部分前面的数字加 1)
例如:2.36 -> 2.4
- ROUND_DOWN
接近零的舍入模式。
在丢弃某部分之前始终不增加数字(从不对舍弃部分前面的数字加1,即截短)。
例如:2.36 -> 2.3
- ROUND_CEILING
接近正无穷大的舍入模式。
如果 BigDecimal 为正,则舍入行为与 ROUND_UP 相同;
如果为负,则舍入行为与 ROUND_DOWN 相同。
相当于是 ROUND_UP 和 ROUND_DOWN 的合集
- ROUND_FLOOR
接近负无穷大的舍入模式。
如果 BigDecimal 为正,则舍入行为与 ROUND_DOWN 相同;
如果为负,则舍入行为与 ROUND_UP 相同。
与 ROUND_CEILING 正好相反
- ROUND_HALF_UP
四舍五入
例如:2.35 -> 2.4
- ROUND_HALF_DOWN
五舍六入
例如:2.35 -> 2.3
- ROUND_HALF_EVEN
如果舍弃部分左边的数字为奇数,则舍入行为与 ROUND_HALF_UP 相同(四舍五入);
如果为偶数,则舍入行为与 ROUND_HALF_DOWN 相同(五舍六入)。
例如:1.15 -> 1.1,1.25 -> 1.2
- ROUND_UNNECESSARY
断言请求的操作具有精确的结果,因此不需要舍入。
如果对获得精确结果的操作指定此舍入模式,则抛出 ArithmeticException。
我觉得剩下得了解下就行,而且我感觉剩下有的就是错的,比如 ROUND_HALF_DOWN 和 ROUND_HALF_EVEN,看下面的结果你就知道我说的是为什么了。
public
运行结果
ROUND_UP,结果:2.4
ROUND_DOWN,结果:2.3
ROUND_CEILING,结果:2.4
ROUND_FLOOR,结果:2.3
ROUND_HALF_UP,结果:2.4
ROUND_HALF_DOWN,结果:2.4 (来给我解释解释这个,说好的五舍六入呢)
ROUND_HALF_EVEN,结果:2.4 (还有这个)
Disconnected from the target VM, address: '127.0.0.1:59637', transport: 'socket'
Exception in thread "main" java.lang.ArithmeticException: Rounding necessary
小结:常用的就是 ROUND_HALF_UP、ROUND_UP 和 ROUND_DOWN,其它的当个笑话就行
比较
a.compareTo(b)
a > b 返回 1;a = b 返回 0;a < b 返回 -1
public
运行结果
a
注意事项
在上面的使用中,我们都用的 String 给 BigDecimal 进行 赋值,而没有使用 double 类型赋值,具体的原因看下面的例子:
public
运行结果:
加法用value结果:1000000.005000000000000000104083408558608425664715468883514404296875
加法用string结果:1000000.005
减法value结果:-999999.994999999999999999895916591441391574335284531116485595703125
减法用string结果:-999999.995
乘法用value结果:5000.000000000000104083408558608425664715468883514404296875000000
乘法用string结果:5000.000
绝对值用value结果:1000000
绝对值用string结果:1000000
除法用value结果:199999999.99999999583666365766
除法用string结果:200000000.00000000000000000000
- System.out.println() 中的数字默认是 double 类型的,double 类型的小数计算不准确
- 使用 BigDecimal 的构造方法传入 double 类型时,计算的结果也是不准确的!
所以我们在使用 BigDecimal 进行赋值的时候,最好使用传入 String 的构造函数,可以确认精度。
参考
https://blog.csdn.net/haiyinshushe/article/details/82721234
https://www.jianshu.com/p/2947868d76eb
https://blog.csdn.net/ochangwen/article/details/51531866