Java——BigInteger 和 BigDecimal

一、简要介绍

在Java中,BigIntegerBigDecimal 是两个用于处理大数和高精度数值的类,分别位于 java.math 包中,在使用时需要导入这个包。它们主要用于需要高精度数学计算的场景,尤其是当普通的基本数据类型(如 intlongfloatdouble)无法满足需求时。

BigIntegerBigDecimal 都继承自 Number 类。

二、BigInteger

BigInteger 用于表示任意精度的整数。它可以存储非常大的整数,超出普通数据类型(如 intlong)的范围。

1、主要特点

  1. 可变大小BigInteger 的大小仅限于可用内存,而不是固定的字节数。所以它可以表示很大的范围与精度。
  2. 不可变性BigInteger 对象是不可变的,每次数学运算(如加、减、乘、除)都会返回一个新的 BigInteger 对象。
  3. 方法:提供了多种方法用于基本的数学运算(如加、减、乘、除)、比较、位运算等。只能使用相应的方法进行这些算数运算,不能直接使用 = - * / 符号运算。
  4. 进制转换:支持不同进制的数值表示和转换。
  5. 性能:虽然 BigInteger 支持任意大小的整数,但其性能通常不如原始数据类型。

2、使用示例

import java.math.BigInteger;

public class Example {
	public static void main(String[] args) {
		BigInteger bigInteger1 = new BigInteger("2222222222222222222222222222222");
		BigInteger bigInteger2 = new BigInteger("1111111111111111111111111111111");

		// 使用对应的方法进行算数运算

		// 加法
		BigInteger result1 = bigInteger1.add(bigInteger2);
		System.out.println("bigInteger1 + bigInteger2 = " + result1);

		// 减法
		BigInteger result2 = bigInteger1.subtract(bigInteger2);
		System.out.println("bigInteger1 - bigInteger2 = " + result2);

		// 乘法
		BigInteger result3 = bigInteger1.multiply(bigInteger2);
		System.out.println("bigInteger1 * bigInteger2 = " + result3);

		// 除法
		BigInteger result4 = bigInteger1.divide(bigInteger2);
		System.out.println("bigInteger1 / bigInteger2 = " + result4);
	}
}

可以看到对于每一个运算方法,返回的结果是一个 BigInteger 的对象,这个对象是一个新的对象,我们可以通过下面这段代码验证一下:

import java.math.BigInteger;

public class Example {
	public static void main(String[] args) {
		BigInteger bigInteger = new BigInteger("23408712384789127348912748932");

		BigInteger result = bigInteger.add(bigInteger);

		System.out.println(result == bigInteger);
	}
}

运行结果:
运行结果

三、BigDecimal

BigDecimal用于表示任意精度的十进制数,适合于需要高精度的浮点数运算,尤其是在财务计算中常常使用。

1、主要特点

  1. 高精度:可以表示任意精度的小数,并可控制小数点后的位数。
  2. 不可变性:与 BigInteger 一样,BigDecimal 对象是不可变的。
  3. 方法:提供了丰富的方法用于数学运算、舍入、比较和格式化等。
  4. 舍入模式:支持多种舍入模式(如向上、向下、四舍五入等),适合各种需求。
  5. 性能:虽然 BigDecimal 提供了高精度计算,但在性能上通常不如基本数据类型。

2、使用示例

import java.math.BigDecimal;
import java.math.RoundingMode;

public class Example {
	public static void main(String[] args) {
		// 创建 BigDecimal 对象
		BigDecimal decimal1 = new BigDecimal("123.456");
		BigDecimal decimal2 = new BigDecimal("789.012");

		// 1. 加法
		BigDecimal sum = decimal1.add(decimal2);
		System.out.println("和: " + sum);  // 输出: 和: 912.468

		// 2. 减法
		BigDecimal difference = decimal1.subtract(decimal2);
		System.out.println("差: " + difference);  // 输出: 差: -665.556

		// 3. 乘法
		BigDecimal product = decimal1.multiply(decimal2);
		System.out.println("积: " + product);  // 输出: 积: 97405.665632

		// 4. 除法,保留2位小数,使用四舍五入模式
		BigDecimal quotient = decimal1.divide(decimal2, 2, RoundingMode.HALF_UP);
		System.out.println("商: " + quotient);  // 输出: 商: 0.16

		// 5. 比较
		int comparison = decimal1.compareTo(decimal2);
		if (comparison < 0) {
			System.out.println(decimal1 + " 小于 " + decimal2);  // 输出: 123.456 小于 789.012
		} else if (comparison > 0) {
			System.out.println(decimal1 + " 大于 " + decimal2);
		} else {
			System.out.println(decimal1 + " 等于 " + decimal2);
		}

		// 6. 舍入,保留1位小数,使用四舍五入模式
		BigDecimal rounded = decimal1.setScale(1, RoundingMode.HALF_UP);
		System.out.println("舍入: " + rounded);  // 输出: 舍入: 123.5

		// 7. 设置小数位数并进行舍入
		BigDecimal scaled = decimal1.setScale(2, RoundingMode.DOWN);
		System.out.println("舍入 (保留2位小数): " + scaled);  // 输出: 舍入 (保留2位小数): 123.45

		// 8. 转换为 double
		double doubleValue = decimal1.doubleValue();
		System.out.println("double值: " + doubleValue);  // 输出: double值: 123.456
	}
}

运行结果:
运行结果

3、除法方法使用注意

在使用 divide() 方法时,需要注意一个事情,如果两个数相除的结果是一个无限小数,则会抛出异常,这里就需要给出精度参数,同时,还应当给出舍入方式参数。我上面的实例代码的使用就是给出了精度和舍入方式参数。下面将对比是否给出精度的差异:

import java.math.BigDecimal;
import java.math.RoundingMode;

public class Example {
	public static void main(String[] args) {
		BigDecimal numerator = new BigDecimal("1");
		BigDecimal denominator = new BigDecimal("3");

		try {
			// 尝试直接除法,会抛出异常,因为 1.0 / 3.0 的结果是无限小数
			BigDecimal result = numerator.divide(denominator);
			System.out.println("结果: " + result); // 这里将不会被执行
		} catch (ArithmeticException e) {
			System.out.println("发生异常: " + e.getMessage());
		}
		
		// 使用 divide() 方法设置精度和舍入模式
		BigDecimal resultWithScale = numerator.divide(denominator, 2, RoundingMode.HALF_UP);
		System.out.println("带有精度设置的结果: " + resultWithScale);  // 输出: 带有精度设置的结果: 0.33
	}
}

运行结果:
运行结果
这里的异常大概意思就是:发生了非终止小数扩展,无法得到一个精确可表示的小数结果。

这里的divide() 方法还有其他的重载,其中一个重载只有两个参数,一个参数是分母,一个参数是舍入方式,这个方法在保留结果的精度时会保留与分子精度一致的精度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值