高精度运算的必备类:BigInteger和BigDecimal

Integer类作为int的包装类,能存储的最大整型值为2^31-1 ,Long类也是有限的,最大为2^63-1,如果想要表示更大的整数,不管是基本数据类型还是它们对应的包装类都无能为力,至于进行运算更是无稽之谈。Java中提供了两个用于高精度计算的类:BigInteger和BigDecimal,这两个类包含的方法、提供的操作与基本类型及其对应的包装类相同,并提供了java.lang.Math的所有相关方法。java.lang.Math提供了一系列静态方法用于科学计算;其方法的参数和返回值类型一般为double型。BigInteger类实现了任意精度的整数运算,BigDecimal实现了任意精度的浮点数运算。
它们都扩展Number类且实现Comparable接口,可以使用new BigInteger(String)或new BigDecimal(String)来创建实例,使用add,substract,multiple,divide和remainder方法完成算数运算,使用compareTo方法比较两个数字的大小。
一、BigInteger类
java.math包下的BigInteger可以表示不可变的任意精度的整数,主要是针对整型大数字的处理类,在运算中可以准确地表示任何大小的整数值,而不会丢失任何信息。
我们来看一下它的构造方法:
//针对超过整数范围的运算(整数最大值:2147483647)
BigInteger(String val)

常用方法:
//加
public BigInteger add(BigInteger val)
//减
public BigInteger subtract(BigInteger val)
//乘
public BigInteger multiply(BigInteger val)
//除
public BigInteger divide(BigInteger val)
//返回商和余数的数组
public BigInteger[] divideAndRemainder(BigInteger val)

import java.math.BigInteger;

public class BigIntegerDemo {
public static void main(String[] args) {
BigInteger bi1 = new BigInteger(“100”);
BigInteger bi2 = new BigInteger(“50”);

BigInteger[] bis = bi1.divideAndRemainder(bi2);
System.out.println(“商:” + bis[0]);
System.out.println(“余数:” + bis[1]);
}
}

//运行结果
商:2
余数:0
二、BigDecimal类
由于float类型和double在计算时很容易丢失精度。但在商业计算中,尤其是与计算货币值相关时,要求数字的精度很高,为此Java提供了java.math.BigDecimal类用来实现任意精度的浮点数运算,可以用它进行精确的货币计算。而且BigDecimal 的对象精度没有限制,如果结果不能终止,那么divide方法会抛出ArithmeticException异常。但是可以通过重载divide(BigDecimal num,int scale,int roundingMode)方法来指定尺度和舍入方式来避免异常,这里的scale 是指小数点后最小的整数位数。
下面我们来看一个丢失精度的实例:
public class BigDecimalDemo {
public static void main(String[] args) {
System.out.println(0.09 + 0.01);
System.out.println(1.0 - 0.32);
System.out.println(1.026 * 100);
System.out.println(1.502 / 100);
System.out.println(1.0 - 0.17);
}
}

//运行结果
0.09999999999999999
0.6799999999999999
102.60000000000001
0.01502
其构造方法如下:
public BigDecimal(double val)
将double转换为BigDecimal ,这是double的二进制浮点值的精确十进制表示。返回的BigDecimal是(10scale × val)是一个整数的最小值。
这个构造函数的结果可能有些不可预测。 可以假设在Java中写入new BigDecimal(0.1)创建一个BigDecimal ,它完全等于0.1,这是因为0.1不能像double (或者作为任何有限长度的二进制分数)精确地表示。 因此,正在被传递给构造的值不是正好等于0.1,虽然表面上。该String构造,在另一方面,是完全可以预测的:写new BigDecimal(“0.1”)创建BigDecimal这正好等于0.1,正如人们所期望的那样。 因此, 一般建议优先使用String constructor。当double必须用作源为BigDecimal ,注意,此构造提供了一个精确的转换; 它不会将double转换为String使用Double.toString(double)方法,然后使用BigDecimal(String)构造函数相同的结果。 要获得该结果,请使用static valueOf(double)方法。
参数:val - double值转换为 BigDecimal 。
异常:NumberFormatException - 如果 val 是无限或N
BigDecimal可以用来做超大的浮点数的运算,比如+ - * /的运算,其中除法运算是最复杂的,因为商的位数可能有除不进的情况,此时需要考虑末位小数点的处理。
常用方法:
import java.math.BigDecimal;

public class BigDecimalDemo2 {
public static void main(String[] args) {
BigDecimal bd1 = new BigDecimal(“0.09”);
BigDecimal bd2 = new BigDecimal(“0.01”);
System.out.println(“加:” + bd1.add(bd2));

BigDecimal bd3 = new BigDecimal(“1.0”);
BigDecimal bd4 = new BigDecimal(“0.32”);
System.out.println(“减:” + bd3.subtract(bd4));

BigDecimal bd5 = new BigDecimal(“1.026”);
BigDecimal bd6 = new BigDecimal(“100”);
System.out.println(“乘:” + bd5.multiply(bd6));

BigDecimal bd7 = new BigDecimal(“1.502”);
BigDecimal bd8 = new BigDecimal(“100”);
System.out.println(“除:” + bd7.divide(bd8));
}
}

//运行结果如下:
加:0.10
减:0.68
乘:102.600
除:0.01502
毫无疑问BigInteger和BigDecimal作为高精度运算的类,在追求更高精度的同时也牺牲了它的运行速度。也许我们在程序开发中不一定会遇见这种高精度计算的设计需求,但是未雨绸缪总是没错的。只有提前做好准备,才能时刻迎接挑战!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值