1. 使用原因
为了避免精度丢失,可以使用BigDecimal来进行浮点数的运算。
浮点数也会有精度的丢失。
代码示例:
/**
* a=0.100000024
* b=0.099999905
* false
*/
float a = 2.0f-1.9f;
float b = 1.8f-1.7f;
System.out.println("a="+a);
System.out.println("b="+b);
System.out.println(a==b);
同时计算机是二进制,表达一个数字的时候,宽度有限,浮点数存进来是一个近似整数的无限不循环的小数,所以计算机只能截断后保存,就存在了精度的丢失,也没办法做到二进制精确的表示。
比如十进制的0.2转化为二进制:
小数 十进制转二进制 对数字不断的乘以2 知道出现只有整数的结果,其中转换的二进制就是计算过程中的 得到的这些数的整数部分的值
0.2 * 2 = 0.4 -> 0
0.4 * 2 = 0.8 -> 0
0.8 * 2 = 1.6 -> 1
0.6 * 2 = 1.2 -> 1
0.2 * 2 = 0.4 -> 0(发生循环)
2. BigDecimal使用方法
BigDecimal可以对浮点数运算并且不丢失精度。
涉及钱的场景可以使用,同时也有一种就是把钱的单位作为分,因为现实中钱也只精确到分,1块就是100分,10块1000分。
2.1 常用方法
创建
创建时使用BigDecimal(String val)构造方法或者BigDecimal.valueOf(double val)静态方法来创建对象
加减乘除
- add 相加
- subtract 相减
- multiply 相乘
- divide 相除
代码示例:
BigDecimal n1 = new BigDecimal("1.0");
BigDecimal n2 = new BigDecimal("0.8");
System.out.println(n1.add(n2));//加
System.out.println(n1.subtract(n2));//减
System.out.println(n1.multiply(n2));//乘
System.out.println(n1.divide(n2));//除 除不尽抛出异常
//使用divide三参数版本 scale表示保留的小数部分 第三个参数是保留规则。
System.out.println(n1.divide(n2,2, RoundingMode.HALF_UP));
大小比较
BigDecimal的大小比较 要使用compareTO()方法 原因后面有讲。
代码示例:
BigDecimal n1 = new BigDecimal("1.0");
BigDecimal n2 = new BigDecimal("0.8");
//大小比较
System.out.println(n1.compareTo(n2));// 1 OR 0 OR -1
保留小数
通过setScale 方法设置保留几位小数和保留规则。
BigDecimal n3 = new BigDecimal("3.1415926");
BigDecimal tmp = n3.setScale(3, RoundingMode.HALF_UP);
System.out.println(tmp);//3.142
2.2 BigDecimal的值比较
使用equals()比较的话 会比较两个 一个是值,一个是精度 比如1.0和1.00 那么就是false。 而使用compareTo()不会比较精度
BigDecimal n4 = new BigDecimal("1.0");
BigDecimal n5 = new BigDecimal("1.00");
System.out.println(n4.equals(n5));//false
System.out.println(n4.compareTo(n5));//true