Java中的高精度运算

手写笔记转换

📦 BigInteger类和BigDecimal类

BigInteger类支持任意精度的整数,表示任何大小的整数

BigDecimal类支持任意长度的小数

BigInteger类和BigDecimal都是不可变类,一旦创建其值无法更改,只要产生计算操作就会产生新的对象


🛠️ BigInteger创建方法

📌 通过有参构造器

  • BigInteger(String val)
  • BigInteger(byte[] val)

💡 通过valueOf()静态方法

BigInteger.valueOf(long val)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import java.math.BigInteger;

public class BigIntegerExample {
    public static void main(String[] args) {
        // 从 long 值创建 BigInteger 对象
        BigInteger bigInt2 = BigInteger.valueOf(123456789L);

        System.out.println(bigInt2);  // 输出:123456789
    }
}

⌨️ BigDecimal创建方法

📌 通过有参构造器

创建方式示例注意事项
BigDecimalnew BigDecimal(String val)new BigDecimal("123.456789")推荐通过字符串创建,精度不会丢失。
new BigDecimal(double val)new BigDecimal(123.456)精度可能丢失,尽量避免使用。
new BigDecimal(long val)new BigDecimal(123)使用 long 值创建。
new BigDecimal(int val)new BigDecimal(123)使用 int 值创建。
new BigDecimal(byte[] val)new BigDecimal(byteArray)用字节数组创建。

🧪 通过静态方法valueOf()

1
2
3
4
5
6
7
8
9
import java.math.BigDecimal;

public class BigDecimalExample {
    public static void main(String[] args) {
        // 从 long 值创建 BigDecimal 对象
        BigDecimal decimal1 = BigDecimal.valueOf(123456789L);
        System.out.println(decimal1);  // 输出:123456789
    }
}

创建 BigDecimal 时优先使用字符串类型的构造方法,以避免 double 转换时精度丢失。


🧮 计算方法

操作BigInteger 方法BigDecimal 方法
加法add()add()
减法subtract()subtract()
乘法multiply()multiply()
除法divide()divide()
取余mod()remainder()
幂运算pow()pow()
比较compareTo()compareTo()
相反数negate()negate()

⚙️ BigDecimal保证精度不丢失的机制

BigDecimal 能够保证精度,是因为它使用了任意精度的整数表示法,而不是浮动的二进制表示。

BigDecimal 内部使用两个字段存储数字,一个是整数部分 intVal,另一个是用来表示小数点的位置 scale,避免了浮点数转化过程中可能的精度丢失。

计算时通过整数计算,再结合小数点位置和设置的精度与舍入行为,控制结果精度,避免了由默认浮点数舍入导致的误差。


💻 源码展示

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
public class BigDecimal extends Number implements Comparable<BigDecimal> {
    private final BigInteger intVal;  // 存储整数部分
    private final int scale;          // 存储小数点的位置

    public BigDecimal(String val) {
        // 使用 BigInteger 来表示数值
        intVal = new BigInteger(val.replace(".", ""));
        scale = val.contains(".") ? val.length() - val.indexOf(".") - 1 : 0;
    }
}
그 경기 끝나고 좀 멍하기 있었는데 여러분 이제 살면서 여러가
使用 Hugo 构建
主题 StackJimmy 设计