Java浮点型案例怎么避免精度差

wen java案例 26

本文目录导读:

Java浮点型案例怎么避免精度差

  1. 使用 BigDecimal 类(推荐)
  2. 货币计算使用整型(分/厘为单位)
  3. 使用 Math 类的方法(简单场景)
  4. 比较浮点数时的正确处理
  5. 完整的实用工具类

在Java中避免浮点型精度差的常用方法有以下几种:

使用 BigDecimal 类(推荐)

import java.math.BigDecimal;
import java.math.RoundingMode;
public class BigDecimalExample {
    public static void main(String[] args) {
        // 使用字符串构造,避免精度问题
        BigDecimal num1 = new BigDecimal("0.1");
        BigDecimal num2 = new BigDecimal("0.2");
        // 加法
        BigDecimal sum = num1.add(num2);
        System.out.println("0.1 + 0.2 = " + sum); // 输出: 0.3
        // 减法
        BigDecimal diff = num1.subtract(num2);
        // 乘法
        BigDecimal product = num1.multiply(num2);
        // 除法(需要指定精度和舍入模式)
        BigDecimal quotient = num1.divide(num2, 10, RoundingMode.HALF_UP);
        // 设置精度
        BigDecimal result = new BigDecimal("10.12345");
        result = result.setScale(2, RoundingMode.HALF_UP);
        System.out.println("保留2位小数: " + result); // 输出: 10.12
    }
}

货币计算使用整型(分/厘为单位)

public class CurrencyExample {
    public static void main(String[] args) {
        // 以分为单位存储
        long priceInCents = 1099; // 10.99元
        // 显示时转换
        double displayPrice = priceInCents / 100.0;
        System.out.println("价格: " + displayPrice + "元");
        // 计算时用整型
        long quantity = 3;
        long totalInCents = priceInCents * quantity;
        System.out.println("总价: " + totalInCents / 100.0 + "元");
    }
}

使用 Math 类的方法(简单场景)

public class MathExample {
    public static void main(String[] args) {
        double value = 3.1415926;
        // 四舍五入到指定小数位
        double rounded = Math.round(value * 100.0) / 100.0;
        System.out.println("四舍五入到2位小数: " + rounded);
        // 向上取整
        double ceil = Math.ceil(value * 100) / 100;
        System.out.println("向上取整到2位小数: " + ceil);
        // 向下取整
        double floor = Math.floor(value * 100) / 100;
        System.out.println("向下取整到2位小数: " + floor);
    }
}

比较浮点数时的正确处理

public class CompareExample {
    public static void main(String[] args) {
        double a = 0.1 + 0.2;
        double b = 0.3;
        // 错误方式
        System.out.println(a == b); // false
        // 正确方式:使用误差范围
        double epsilon = 1e-10;
        System.out.println(Math.abs(a - b) < epsilon); // true
        // 使用 BigDecimal 比较
        BigDecimal bd1 = new BigDecimal("0.1").add(new BigDecimal("0.2"));
        BigDecimal bd2 = new BigDecimal("0.3");
        System.out.println(bd1.compareTo(bd2) == 0); // true
    }
}

完整的实用工具类

import java.math.BigDecimal;
import java.math.RoundingMode;
public class DecimalUtil {
    // 默认精度
    private static final int DEFAULT_SCALE = 2;
    // 安全创建 BigDecimal
    public static BigDecimal create(String value) {
        return new BigDecimal(value);
    }
    // 安全加法
    public static BigDecimal add(String v1, String v2) {
        return new BigDecimal(v1).add(new BigDecimal(v2));
    }
    // 安全减法
    public static BigDecimal subtract(String v1, String v2) {
        return new BigDecimal(v1).subtract(new BigDecimal(v2));
    }
    // 安全乘法
    public static BigDecimal multiply(String v1, String v2) {
        return new BigDecimal(v1).multiply(new BigDecimal(v2));
    }
    // 安全除法
    public static BigDecimal divide(String v1, String v2, int scale) {
        return new BigDecimal(v1).divide(new BigDecimal(v2), scale, RoundingMode.HALF_UP);
    }
    // 格式化输出
    public static String format(BigDecimal value) {
        return value.setScale(DEFAULT_SCALE, RoundingMode.HALF_UP).toString();
    }
    // 使用示例
    public static void main(String[] args) {
        String result = format(add("0.1", "0.2"));
        System.out.println("0.1 + 0.2 = " + result); // 输出: 0.30
    }
}
  1. 财务计算:始终使用 BigDecimal,并用字符串构造
  2. 普通业务逻辑:使用整型(如分为单位)
  3. 性能要求高:使用 double+误差比较
  4. 数据库存储:使用 DECIMAL 类型
  5. API 返回值:使用字符串类型传输精确值

永远不要使用 比较浮点数,使用 BigDecimal.compareTo() 或误差范围比较。

抱歉,评论功能暂时关闭!