转载于:https://blog.csdn.net/cen_s/article/details/76472834
在日常开发中我们经常会碰到小数计算,而小数直接计算的话会出现一些小小的错误,如下
System.out.println(1.01 + 2.02);
你说能输出什么?3.03?实际上输出的是3.0300000000000002。这是因为不论是float 还是double都是浮点数,而计算机是二进制的,浮点数会失去一定的精确度。有没有不失精度的办法呢?这里就要用到BigDecimal了。
java.math.BigDecimal。Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数。在实际应用中,需要对更大或者更小的数进行运算和处理。float和double只能用来做科学计算或者是工程计算,在商业计算中要用java.math.BigDecimal。BigDecimal所创建的是对象,我们不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。构造器是类的特殊方法,专门用来创建对象,特别是带有参数的对象。
创建BigDecimal对象主要有两种。
-
BigDecimal b1 =
new BigDecimal(
"1.34");
//1.34
-
BigDecimal b2 = BigDecimal.valueOf(
1.34);
//1.34
其中b1也可以写成new BigDecimal(Double.toString(1.34)),可以直接new BigDecimal(1.34)吗,也是可以的,只是会出现上述的精度问题。
-
BigDecimal one1 =
new BigDecimal(
1.34);
//1.3400000000000000799360577730112709105014801025390625
-
BigDecimal two1 =
new BigDecimal(
"1.34");
//1.34
除了这两种外,特殊的像0、1、10可以这样写。
BigDecimal zero = BigDecimal.ZERO; BigDecimal one = BigDecimal.ONE; BigDecimal ten = BigDecimal.TEN;
-
public static BigDecimal valueOf(long val) {
-
if (val >=
0 && val < zeroThroughTen.length)
-
return zeroThroughTen[(
int)val];
-
else
if (val != INFLATED)
-
return
new BigDecimal(
null, val,
0,
0);
-
return
new BigDecimal(INFLATED_BIGINT, val,
0,
0);
-
}
-
// Cache of common small BigDecimal values.
-
private
static
final BigDecimal zeroThroughTen[] = {
-
new BigDecimal(BigInteger.ZERO,
0,
0,
1),
-
new BigDecimal(BigInteger.ONE,
1,
0,
1),
-
new BigDecimal(BigInteger.valueOf(
2),
2,
0,
1),
-
new BigDecimal(BigInteger.valueOf(
3),
3,
0,
1),
-
new BigDecimal(BigInteger.valueOf(
4),
4,
0,
1),
-
new BigDecimal(BigInteger.valueOf(
5),
5,
0,
1),
-
new BigDecimal(BigInteger.valueOf(
6),
6,
0,
1),
-
new BigDecimal(BigInteger.valueOf(
7),
7,
0,
1),
-
new BigDecimal(BigInteger.valueOf(
8),
8,
0,
1),
-
new BigDecimal(BigInteger.valueOf(
9),
9,
0,
1),
-
new BigDecimal(BigInteger.TEN,
10,
0,
2),
-
};
发现10以内的对象都是同一个,所以为true。
BigDecimal的加减乘除运算。
-
public BigDecimal add(BigDecimal value);
//加法
-
public BigDecimal subtract(BigDecimal value);
//减法
-
public BigDecimal multiply(BigDecimal value);
//乘法
-
public BigDecimal divide(BigDecimal value);
//除法
也可以照下面加法例子写成一个util,另外三个都差不多就不展开了。
-
public static double add(double value1,double value2){
-
BigDecimal b1 =
new BigDecimal(Double.toString(value1));
-
BigDecimal b2 =
new BigDecimal(Double.toString(value2));
-
return b1.add(b2).doubleValue();
-
}
BigDecimal的运算都没有对原值进行操作,而是返回一个新的BigDecimal对象,这点可能有些小伙伴会搞错要注意一下。
-
BigDecimal b1 =
new BigDecimal(
"1.34");
-
System.out.println(
"b1: " + b1);
-
BigDecimal b2 =
new BigDecimal(
"2.34");
-
b1.add(b2);
-
System.out.println(
"b1: " + b1);
//b1并没有变
BigDecimal的比较用的是BigDecimal的compareTo方法,将此 BigDecimal 与指定的 BigDecimal 比较。
根据此方法,值相等但具有不同标度的两个BigDecimal对象(如,2.0 和 2.00)被认为是相等的。
当此 BigDecimal 在数字上小于、等于或大于被比较对象时,返回 -1、0 或 1。
-
BigDecimal one = BigDecimal.valueOf(
1);
-
BigDecimal two = BigDecimal.valueOf(
2);
-
BigDecimal three = one.add(two);
-
int i1 = one.compareTo(two);
//-1
-
int i2 = two.compareTo(two);
//0
-
int i3 = three.compareTo(two);
//1
</div>