大数操作——BigInteger、BigDecimal

今天又是收获的一天~~
关于学习大数操作来源于一道编程题:以字符串的形式读入两个数字,编写一个函数计算它们的和,以字符串形式返回。
当时我看到这道题第一反应就是把两个串通过nteger.valueOf()转为Integer然后想加,但事实并没有这么简单,不然怎末叫大数相加呢~

好了,来进入正题

我们知道在Java中,存储整行最大的范围就是long类型----64比特位,但是如果大于这个值又改怎末办?
同样的,对于浮点数double类型的精度只能达到16为,要是精度高于16位呢?

这里就引入了大数操作——BigInteger、BigDecimal;他们都在java.math包下,并且都是以字符串的形式存储的。

BigInteger

java.math.BigInteger就是用来表示任意大小的整数。BigInteger内部用一个 int[ ] 数组来模拟一个非常大的整数;
在这里插入图片描述
大数也可以转为基本类型,但是如果超出了基本类型的范围,转换时将丢失高位信息,即结果不一定是准确的。

BigInteger和Integer、Long一样,也是不可变类,并且也继承自Number类。因为Number定义了转换为基本类型的几个方法:

  • 转换为byte:byteValue()
  • 转换为short:shortValue()
  • 转换为int:intValue()
  • 转换为long:longValue()
  • 转换为float:floatValue()
  • 转换为double:doubleValue()

如果需要准确地转换成基本类型,可以使用intValueExact()、longValueExact()等方法,在转换时如果超出范围,将直接抛出ArithmeticException异常。

代码:

BigInteger i1 = new BigInteger("1234567890");
BigInteger i2 = new BigInteger("12345678901234567890");
BigInteger sum = i1.add(i2); // 12345678902469135780

BigInteger n = new BigInteger("999111").pow(5);
float f = n.floatValue()
System.out.println(f);

BigDecimal

BigDecimal与BigInteger类似,BigDecimal可以表示一个任意大小且精度完全准确的浮点数。

构造方法:

  • BigDecimal(double val); 将double类型转换为BigDecimal类型
  • BigDecimal(BigInteger val); 将BigInteger类型转换为BigDecimal类型
  • BigDecimal(String val); 将十进制String类型的浮点数转为BigDecimal类型

BigDecimal底层实现:
我们通过查看BigDecimal的源码:

public class BigDecimal extends Number implements Comparable<BigDecimal> {
    private final BigInteger intVal;
    private final int scale;
}

可以发现,一个BigDecimal是通过一个BigInteger和一个scale来表示的,即BigInteger表示一个完整的整数,而scale表示小数位数

常用方法:

  • add(BigDecimal augend) 加法运算
  • subtract(BigDecimal subtrahend) 减法运算
  • multiply(BigDecimal multiplicand) 乘法运算
  • divide(BigDecimal divisor) 除法运算,可能会产生除零异常和不能整除异常。
  • toString(): 将BigDecimal对象的数值转换成字符串
  • doubleValue() :将BigDecimal对象中的值以双精度数返回
  • floatValue(): 将BigDecimal对象中的值以单精度数返回
  • intValue() :将BigDecimal对象中的值以整数返回
  • scale():表示小数位数
  • equas():判断两个BigDecimal是否相同,使用equals()方法不但要求两个BigDecimal的值相等,还要求它们的scale()相等:
  • compareTo():它根据两个值的大小分别返回负数、正数和0,分别表示小于、大于和等于

注意:

  • 对BigDecimal做加、减、乘时,精度不会丢失,但是做除法时,存在无法除尽的情况,这时,就必须指定精度以及如何进行截断
	BigDecimal b1 = new BigDecimal("123.456");
	BigDecimal b2 = new BigDecimal("23.456789");
	BigDecimal b3 = b1.divide(b2, 10, RoundingMode.HALF_UP); // 保留10位小数并四舍五入
	BigDecimal b4 = b1.divide(b2); // 报错:ArithmeticException,因为除不尽
  • BigDecimal都是不可变的(immutable)的,在进行每一步运算时,都会产生一个新的对象,所以在做运算时千万要保存操作后的值。
  • 使用BigDecimal的坏处是性能比double和float差,在处理庞大,复杂的运算时尤为明显,因根据实际需求决定使用哪种类型
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值