On this page

Java浮点数运算

Java 浮点数运算

Java 提供了两种浮点数类型:float(32位)和double(64位),用于处理带有小数部分的数值。以下是 Java 中浮点数运算的详细说明。

一、浮点数类型

类型大小范围精度默认值后缀
float32位±1.4E-45 到 ±3.4E+386-7位有效数字0.0ff/F
double64位±4.9E-324 到 ±1.7E+30815位有效数字0.0dd/D(可选)

二、基本浮点运算

Java 支持以下浮点运算符:

public class BasicFloatOperations {
    public static void main(String[] args) {
        double a = 10.5;
        double b = 3.2;
        
        // 加法
        System.out.println(a + " + " + b + " = " + (a + b));  // 13.7
        
        // 减法
        System.out.println(a + " - " + b + " = " + (a - b));  // 7.3
        
        // 乘法
        System.out.println(a + " * " + b + " = " + (a * b));  // 33.6
        
        // 除法
        System.out.println(a + " / " + b + " = " + (a / b));  // 3.28125
        
        // 取余
        System.out.println(a + " % " + b + " = " + (a % b));  // 1.0999999999999996
        
        // 混合运算
        System.out.println("5.0 / 2 = " + (5.0 / 2));  // 2.5 (至少一个操作数是浮点数)
    }
}

三、浮点数特殊值

Java 浮点数有三个特殊值:

public class SpecialFloatValues {
    public static void main(String[] args) {
        // 正无穷大
        double posInf = Double.POSITIVE_INFINITY;
        System.out.println("正无穷大: " + posInf);  // Infinity
        
        // 负无穷大
        double negInf = Double.NEGATIVE_INFINITY;
        System.out.println("负无穷大: " + negInf);  // -Infinity
        
        // NaN (Not a Number)
        double nan = Double.NaN;
        System.out.println("NaN: " + nan);  // NaN
        
        // 产生这些值的运算
        System.out.println("1.0 / 0.0 = " + (1.0 / 0.0));  // Infinity
        System.out.println("-1.0 / 0.0 = " + (-1.0 / 0.0));  // -Infinity
        System.out.println("0.0 / 0.0 = " + (0.0 / 0.0));  // NaN
    }
}

四、浮点数精度问题

浮点数运算存在精度问题,这是由二进制浮点表示法导致的:

public class PrecisionIssues {
    public static void main(String[] args) {
        // 精度问题示例
        System.out.println(0.1 + 0.2);  // 0.30000000000000004
        
        // 比较浮点数 - 错误方式
        double d1 = 0.1 + 0.2;
        double d2 = 0.3;
        System.out.println(d1 == d2);  // false
        
        // 比较浮点数 - 正确方式 (使用误差范围)
        double epsilon = 0.000001;
        System.out.println(Math.abs(d1 - d2) < epsilon);  // true
    }
}

五、Math 类常用方法

Math 类提供了许多浮点数运算方法:

public class MathClassMethods {
    public static void main(String[] args) {
        // 四舍五入
        System.out.println("Math.round(3.4): " + Math.round(3.4));  // 3
        System.out.println("Math.round(3.6): " + Math.round(3.6));  // 4
        
        // 向上取整
        System.out.println("Math.ceil(3.2): " + Math.ceil(3.2));  // 4.0
        
        // 向下取整
        System.out.println("Math.floor(3.8): " + Math.floor(3.8));  // 3.0
        
        // 绝对值
        System.out.println("Math.abs(-4.5): " + Math.abs(-4.5));  // 4.5
        
        // 最大值和最小值
        System.out.println("Math.max(3.2, 5.7): " + Math.max(3.2, 5.7));  // 5.7
        System.out.println("Math.min(3.2, 5.7): " + Math.min(3.2, 5.7));  // 3.2
        
        // 幂运算
        System.out.println("Math.pow(2, 3): " + Math.pow(2, 3));  // 8.0
        
        // 平方根
        System.out.println("Math.sqrt(16): " + Math.sqrt(16));  // 4.0
        
        // 三角函数
        System.out.println("Math.sin(Math.PI/2): " + Math.sin(Math.PI/2));  // 1.0
        System.out.println("Math.cos(Math.PI): " + Math.cos(Math.PI));  // -1.0
        
        // 随机数 [0.0, 1.0)
        System.out.println("Math.random(): " + Math.random());
    }
}

六、BigDecimal 精确计算

对于需要高精度的金融计算,推荐使用 BigDecimal

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

public class BigDecimalExample {
    public static void main(String[] args) {
        // 使用字符串构造BigDecimal避免精度问题
        BigDecimal bd1 = new BigDecimal("0.1");
        BigDecimal bd2 = new BigDecimal("0.2");
        
        // 加法
        System.out.println("0.1 + 0.2 = " + bd1.add(bd2));  // 0.3
        
        // 减法
        System.out.println("0.1 - 0.2 = " + bd1.subtract(bd2));  // -0.1
        
        // 乘法
        System.out.println("0.1 * 0.2 = " + bd1.multiply(bd2));  // 0.02
        
        // 除法 (需要指定舍入模式)
        BigDecimal bd3 = new BigDecimal("10");
        BigDecimal bd4 = new BigDecimal("3");
        System.out.println("10 / 3 = " + 
            bd3.divide(bd4, 4, RoundingMode.HALF_UP));  // 3.3333
        
        // 比较
        System.out.println("0.1 + 0.2 == 0.3? " + 
            bd1.add(bd2).equals(new BigDecimal("0.3")));  // true
    }
}

七、浮点数运算最佳实践

  1. 避免直接比较浮点数:使用误差范围或 BigDecimal
  2. 金融计算使用 BigDecimal:避免精度损失
  3. 注意类型转换
    double d = 5 / 2;  // 2.0 (整数除法结果转换为double)
    double d2 = 5.0 / 2;  // 2.5 (至少一个操作数是浮点数)
    
  4. 谨慎使用浮点数循环计数器
    // 不推荐 - 可能因精度问题导致无限循环
    for (double d = 0.0; d != 1.0; d += 0.1) {
        System.out.println(d);
    }
    
  5. 了解 NaN 的特殊性
    double nan = Double.NaN;
    System.out.println(nan == nan);  // false
    System.out.println(Double.isNaN(nan));  // true
    

通过理解这些概念和技术,您可以在 Java 程序中正确有效地进行浮点数运算。