BigDecimal

远离那些贬低你理想的人。狭隘的人经常如此,伟大的人会让你感觉自己也可以变好。
——马克·吐温

为什么需要 BigDecimal?

Java 的基本数据类型 doublefloat 使用二进制浮点数表示,会导致精度问题:

System.out.println(0.1 + 0.2);  // 输出 0.30000000000000004

浮点类型 Float 和 Double,但这些类型因为不是高精度,也不是 SQL 标准的类型,会出现精度损失的问题,可以使用BigDecime解决

double的实现

  • 数据结构:double在Java中是基本数据类型,使用64位来表示。其结构如下:

    • 1位符号位:表示正负。

    • 11位指数:表示数值的范围。

    • 52位尾数:表示有效数字

      public final class Double {
          public static final double NaN = 0.0d / 0.0; // 表示非数
          public static final double POSITIVE_INFINITY = 1.0d / 0.0; // 表示正无穷
          // 其他方法...
      }
      
      

BigDecimal的实现

  • 数据结构:BigDecimal是一个类,主要由两个部分构成:

    • int[] 整数部分:存储数字的有效位。

    • int scale:表示小数点的位置,决定小数部分的位数。

      public final class BigDecimal {
          private final int[] intVal; // 存储数值的整数部分
          private final int scale; // 小数点位置
          private transient int precision; //表示数字的有效位数
          // 构造方法和其他方法...
      }
      
      

核心特性

  1. 不可变性:所有运算都会返回新的 BigDecimal 对象
  2. 任意精度:可以表示任意大小的数,没有范围限制
  3. 精确计算:避免了浮点数的精度问题

创建 BigDecimal

// 推荐使用字符串构造
BigDecimal bd1 = new BigDecimal("0.1");
BigDecimal bd2 = BigDecimal.valueOf(0.1);  // 推荐方式

// 不推荐使用double构造
BigDecimal bd3 = new BigDecimal(0.1);  // 会有精度问题

常用运算

BigDecimal a = new BigDecimal("10.5");
BigDecimal b = new BigDecimal("3.2");

// 加法
BigDecimal sum = a.add(b);  // 13.7

// 减法
BigDecimal difference = a.subtract(b);  // 7.3

// 乘法
BigDecimal product = a.multiply(b);  // 33.60

// 除法(需要指定舍入模式)
BigDecimal quotient = a.divide(b, 2, RoundingMode.HALF_UP);  // 3.28

// 比较
int result = a.compareTo(b);  // 1 (a > b)
posted @ 2025-03-27 15:16  Tsukinor  阅读(31)  评论(0)    收藏  举报