在看《阿里巴巴开发手册》里面提到浮点数之间的等值判断不要用 ==,而是指定误差范围或用BigDecimal,然后才记忆起备忘录里BigDecimal还没写呢,就这篇幅写了一星期,因为实习完全没有时间啊啊啊啊啊啊啊啊
1. BigDecimal介绍
背景
我们知道计算机都是以二进制的形式存储数据的,而我们日常则是使用十进制,那么我们的 数字
存进计算机则需一个进制转换的过程,这过程就会损失精度的,就导致浮点数不能用等值判断
原因
十进制的0.1
转换 成二进制为 0.00011001...
,是无限小数,计算机存不下只能截取。后面这截取的无限小数还原成十进制就会损失精度不准确,不能用等值判断了
救星
BigDecimal的横空出世是为了解决浮点数的精度问题,其全限定类名为 java.math.BigDecimal,BigDecimal是一个对象,代表着不变的,任意精度的带符号的十进制数字,我们要使用该对象的方法来进行加减乘除的操作
原理
既然十进制小数转成二进制会损失精度,那么把十进制小数扩大成整数再转成二进制则会保持精度了
2. BigDecimal基本使用
2.1 常见构造方法
方法
描述
BigDecimal(int val)
将int转换成BigDecimal
BigDecimal(int val, MathContext mc)
根据上下设置进行舍入
BigDecimal(long val)
将long转换成BigDecimal
BigDecimal(double)
将double转换成BigDecimal
BigDecimal(String)
将String转换成BigDecimal
MathContext(int setPrecision, RoundingMode setRoundingMode)
上下文取舍(精度,舍入模式)
阿里手册规约:禁止使用构造方法 BigDecimal(double)的方式把 double 值转化为 BigDecimal 对象
BigDecimal num1 = new BigDecimal(0.1);
BigDecimal num2 = new BigDecimal("0.1");
System.out.println(num1); // 0.1000000000000000055511151231257827021181583404541015625
System.out.println(num2); // 0.1
因为浮点数并不是一个准确的值,而String类型的就确定
2.2 常用方法
方法
描述
abs()
返回一个绝对值BigDecimal对象
scale()
小数位数,包含末尾零。返回负数表示是一个正数,且有负数位0
stripTrailingZeros()
除去末尾的零,包含整数
add(BigDecimal augend)
被加数
add(BigDecimal augend, MathContext mc)
根据上下文取舍
subtract(BigDecimal subtrahend)
被减数
multiply(BigDecimal multiplicand)
被乘数
divide(BigDecima divisor, int roundingMode)
被除数,要指定上下文取舍,否则报错
divideAndRemainder(BigDecimal divisor)
求余
compareTo(BigDecimal val)
比较数值大小,equals要求scale()相同,且值相同
toString()
转成字符串
intValue()
转成整型
longValue()
转成长整型
BigDecimal num1 = new BigDecimal("0.01234");
BigDecimal num2 = new BigDecimal("0.56789");
-------------------------------------------------------------------
System.out.println(num1.add(num2));
System.out.println(num1.subtract(num2));
// 小数保留6位,四舍五入
System.out.println(num1.multiply(num2,new MathContext(6, RoundingMode.HALF_UP)));
// 小数保留4位,直接截取
System.out.println(num1.divide(num2,new MathContext(4,RoundingMode.DOWN)));
// 0.58023
// -0.55555
// 0.00700776
// 0.02172
-------------------------------------------------------------------
BigDecimal num1 = new BigDecimal("0.123");
BigDecimal num2 = new BigDecimal("0.123000");
System.out.println(num1.equals(num2));
System.out.println(num1.compareTo(num2));
// false
// 0
除法存在除不尽的情况,所以一定要使用上下文取舍器
BigDecimal比较用compareTo,而equals要求scale()即小数位数相同
ArithmeticException常见的算数异常
3. BigInteger
Java原生提供的最大整型是长整型,占8字节64位,范围是-9223372036854775808 ~ 9223372036854775807,如果超过了这个范围,那么可以用不可变的BigInteger对象,其原理是内部使用 int[] 数组来模拟大数
3.1 常见构造函数
函数
描述
BigInteger(byte[] val)
BigInteger(String) val)
3.2 常见方法
方法
描述
add(BigInteger) val)
加法
subtract(BigInteger val)
BigInteger num1 = new BigInteger("1234567890");
System.out.println(num1.pow(5)); // 2867971860299718107233761438093672048294900000
BigInteger num2 = new BigInteger("123456");
long num3 = num2.longValue();
System.out.println(num3); // 123456
我的博客即将同步至 OSCHINA 社区,这是我的 OSCHINA ID:osc_45632688,邀请大家一同入驻:https://www.oschina.net/sharing-plan/apply
本文分享 CNBlog - Howlet。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。