BigInteger类与BigDecimal类

我们为什么需要BigInteger类与BigDecimal类?

  当年我在深圳某金融公司当程序员时,负责的是财务部分程序。要知道对于财务来说,一分钱的误差就会导致各种借贷不平,最终整个报表都不能看。而金融公司的业务量大、金额也大,简单的用四舍五入的话,经常会出现尾差问题,让人头痛。尾插都还是可以解释的,但误差就不能忍了,那么,Java中有误差吗?答案是肯定的,看一个最简单的例子:

public class Test {

	public static void main(String[] args) {

		double a = 1.2;
		double b = a - 0.1;
		System.out.println(b);

	}
}
--------------------------------------------------------
输出结果为:
1.0999999999999999

  尽管就差这么一点点,但数据量一上去,一亿条数据都差这么一点,总误差就体现出来了。而且在某些复杂的计算情况,使用float和double误差更大。

  那么,如何在Java中获得准确的数呢?这时就要用到Java提供的BigDecimal类了。

  另一个问题:如果我们使用的整数范围超过了long型怎么办?这个时候,就只能用软件来模拟一个大整数。BigInteger类就是用来表示任意大小的整数的。

BigInteger类

  BigInteger位于java.math包下,创建实例:

		BigInteger bi = new BigInteger("1234567890");

  BigInteger做运算的时候,只能使用实例方法,而不能使用运算符。实例:

public class Test {

	public static void main(String[] args) {

		BigInteger bi1 = new BigInteger("1234567890");
		BigInteger bi2 = new BigInteger("12345");
		System.out.println(bi1.add(bi2));
	}
}
--------------------------------------------------------
输出结果为:
1234580235

  当我们需要将BigInteger类转换为基本数据类型时,可以调用longValueExact()等方法,实例:

public class Test {

	public static void main(String[] args) {

		BigInteger bi1 = new BigInteger("1234567890");
		long longValueExact = bi1.longValueExact();
		System.out.println(longValueExact);
	}
}

  和long型整数运算比,BigInteger不会有范围限制,但缺点是速度比较慢。

BigDecimal类

  和BigInteger类似,BigDecimal可以表示一个任意大小且精度完全准确的浮点数,创建实例:

public class Test {

	public static void main(String[] args) {

		BigDecimal bd = new BigDecimal("123.456789");
		System.out.println(bd);
	}
}
------------------------------------------------
输出结果为:
123.456789

  BigDecimal类中提供了scale()方法,来获取小数的位数,返回值为int类型:

public class Test {

	public static void main(String[] args) {

		BigDecimal bd = new BigDecimal("123.456789");
		int scale = bd.scale();
		System.out.println(scale);
	}
}
-----------------------------------------------------
输出结果为:
6

  对BigDecimal做加、减、乘时,精度不会丢失,但是做除法时,存在无法除尽的情况,这时,就必须指定精度以及如何进行截断:

public class Test {

	public static void main(String[] args) {

		BigDecimal d1 = new BigDecimal("123.456");
		BigDecimal d2 = new BigDecimal("23.456789");
		BigDecimal d3 = d1.divide(d2, 10, RoundingMode.HALF_UP); // 保留10位小数并四舍五入
		BigDecimal d4 = d1.divide(d2); // 报错:ArithmeticException,因为除不尽

	}
}

  在比较两个BigDecimal的值是否相等时,要特别注意,使用equals()方法不但要求两个BigDecimal的值相等,还要求它们的scale()相等:

public class Test {

	public static void main(String[] args) {

		BigDecimal d1 = new BigDecimal("123.456");
		BigDecimal d2 = new BigDecimal("123.45600");
		System.out.println(d1.equals(d2)); // false,因为scale不同
		System.out.println(d1.equals(d2.stripTrailingZeros())); // true,因为d2去除尾部0后scale变为2
		System.out.println(d1.compareTo(d2)); // 0表示相等,-1表示比d2小,1表示比d1大
	}
}
----------------------------------------------------------------
输出结果为:
false
true
0

  所以我们在比较BigDecimal的值的时候,最好都使用compareTo()方法。

发布了18 篇原创文章 · 获赞 0 · 访问量 404

猜你喜欢

转载自blog.csdn.net/HhmFighting/article/details/105012620