float 关键字

概述

float 是Java中的基本数据类型,表示32位单精度IEEE 754浮点数,取值范围约为±3.4E38(6-7位有效数字)。

语法格式

float variableName;               // 声明float变量
float variableName = 3.14f;       // 浮点字面量(必须加f后缀)
float variableName = 1.5F;        // 大写F也可以

基本特性

public class FloatBasicsExample {
    public static void main(String[] args) {
        // 基本声明和初始化
        float f1 = 3.14f;
        float f2 = -2.5f;
        float f3 = 1.234567f;     // 精度有限
        float f4 = 0.0f;

        System.out.println("f1 = " + f1);
        System.out.println("f2 = " + f2);
        System.out.println("f3 = " + f3);
        System.out.println("f4 = " + f4);

        // 常量值
        System.out.println("float最小正值: " + Float.MIN_VALUE);
        System.out.println("float最大值: " + Float.MAX_VALUE);
        System.out.println("float最小正常值: " + Float.MIN_NORMAL);
        System.out.println("float精度位数: " + Float.SIZE);

        // 特殊值
        float positiveInfinity = Float.POSITIVE_INFINITY;
        float negativeInfinity = Float.NEGATIVE_INFINITY;
        float notANumber = Float.NaN;

        System.out.println("正无穷: " + positiveInfinity);
        System.out.println("负无穷: " + negativeInfinity);
        System.out.println("非数字: " + notANumber);

        // 科学计数法
        float scientific1 = 1.23e4f;    // 1.23 × 10^4
        float scientific2 = 5.67e-3f;   // 5.67 × 10^-3

        System.out.println("科学计数法1.23e4: " + scientific1);
        System.out.println("科学计数法5.67e-3: " + scientific2);

        // 精度限制示例
        float precise = 1.23456789f;
        System.out.println("float精度限制: " + precise); // 只能保持约7位有效数字
    }
}

类型转换

public class FloatConversionExample {
    public static void main(String[] args) {
        // 自动类型转换(从整数到float)
        byte b = 100;
        short s = 1000;
        int i = 100000;
        long l = 1000000L;

        float fromByte = b;
        float fromShort = s;
        float fromInt = i;
        float fromLong = l;  // 可能丢失精度

        System.out.println("byte到float: " + fromByte);
        System.out.println("short到float: " + fromShort);
        System.out.println("int到float: " + fromInt);
        System.out.println("long到float: " + fromLong);

        // float到double(自动转换)
        float f = 3.14f;
        double d = f;
        System.out.println("float到double: " + d);

        // 强制类型转换(丢失小数部分)
        float decimal = 3.99f;
        int intFromFloat = (int) decimal;
        long longFromFloat = (long) decimal;

        System.out.println("float转int: " + decimal + " -> " + intFromFloat);
        System.out.println("float转long: " + decimal + " -> " + longFromFloat);

        // 精度丢失示例
        int largeInt = 16777217; // 超过float精度范围
        float floatFromLargeInt = largeInt;
        int backToInt = (int) floatFromLargeInt;

        System.out.println("原始int: " + largeInt);
        System.out.println("转为float: " + floatFromLargeInt);
        System.out.println("转回int: " + backToInt);
        System.out.println("精度丢失: " + (largeInt != backToInt));

        // 字符串转换
        String str = "3.14159";
        float floatFromString = Float.parseFloat(str);
        System.out.println("字符串转float: " + floatFromString);

        // float转字符串
        float value = 2.718f;
        String stringFromFloat = Float.toString(value);
        System.out.println("float转字符串: " + stringFromFloat);
    }
}

浮点数比较

public class FloatComparisonExample {
    public static void main(String[] args) {
        // 浮点数比较的陷阱
        float a = 0.1f + 0.2f;
        float b = 0.3f;

        System.out.println("a = 0.1f + 0.2f = " + a);
        System.out.println("b = 0.3f = " + b);
        System.out.println("a == b: " + (a == b)); // 可能为false!

        // 正确的浮点数比较方法
        float epsilon = 1e-6f; // 容差值
        boolean isEqual = Math.abs(a - b) < epsilon;
        System.out.println("使用容差比较: " + isEqual);

        // 使用Float.compare()
        int comparison = Float.compare(a, b);
        System.out.println("Float.compare(a, b): " + comparison);

        // 特殊值比较
        float nan1 = Float.NaN;
        float nan2 = Float.NaN;
        float infinity = Float.POSITIVE_INFINITY;

        System.out.println("NaN == NaN: " + (nan1 == nan2));           // false
        System.out.println("Float.isNaN(nan1): " + Float.isNaN(nan1)); // true
        System.out.println("Float.isInfinite(infinity): " + Float.isInfinite(infinity)); // true
        System.out.println("Float.isFinite(3.14f): " + Float.isFinite(3.14f)); // true

        // 零值比较
        float positiveZero = 0.0f;
        float negativeZero = -0.0f;

        System.out.println("+0.0f == -0.0f: " + (positiveZero == negativeZero)); // true
        System.out.println("Float.compare(+0.0f, -0.0f): " + 
                          Float.compare(positiveZero, negativeZero)); // 1
    }
}

数学运算

public class FloatMathExample {
    public static void main(String[] args) {
        // 基本算术运算
        float a = 10.5f;
        float b = 3.2f;

        System.out.println("加法: " + a + " + " + b + " = " + (a + b));
        System.out.println("减法: " + a + " - " + b + " = " + (a - b));
        System.out.println("乘法: " + a + " * " + b + " = " + (a * b));
        System.out.println("除法: " + a + " / " + b + " = " + (a / b));
        System.out.println("求余: " + a + " % " + b + " = " + (a % b));

        // 数学函数
        float angle = 45.0f;
        float radians = (float) Math.toRadians(angle);

        System.out.println("\n数学函数:");
        System.out.println("角度 " + angle + "° = " + radians + " 弧度");
        System.out.println("sin(" + angle + "°) = " + Math.sin(radians));
        System.out.println("cos(" + angle + "°) = " + Math.cos(radians));
        System.out.println("tan(" + angle + "°) = " + Math.tan(radians));

        // 其他数学运算
        float x = 2.5f;
        System.out.println("\n其他运算:");
        System.out.println("√" + x + " = " + Math.sqrt(x));
        System.out.println(x + "² = " + Math.pow(x, 2));
        System.out.println("e^" + x + " = " + Math.exp(x));
        System.out.println("ln(" + x + ") = " + Math.log(x));
        System.out.println("ceil(" + x + ") = " + Math.ceil(x));
        System.out.println("floor(" + x + ") = " + Math.floor(x));
        System.out.println("round(" + x + ") = " + Math.round(x));

        // 绝对值和符号
        float negative = -7.3f;
        System.out.println("\n符号运算:");
        System.out.println("abs(" + negative + ") = " + Math.abs(negative));
        System.out.println("signum(" + negative + ") = " + Math.signum(negative));
        System.out.println("max(" + a + ", " + b + ") = " + Math.max(a, b));
        System.out.println("min(" + a + ", " + b + ") = " + Math.min(a, b));
    }
}

实际应用示例

import java.text.DecimalFormat;
import java.util.Random;

public class FloatApplicationExample {

    // 2D图形计算
    public static class Point2D {
        float x, y;

        public Point2D(float x, float y) {
            this.x = x;
            this.y = y;
        }

        public float distanceTo(Point2D other) {
            float dx = this.x - other.x;
            float dy = this.y - other.y;
            return (float) Math.sqrt(dx * dx + dy * dy);
        }

        public Point2D add(Point2D other) {
            return new Point2D(this.x + other.x, this.y + other.y);
        }

        public Point2D scale(float factor) {
            return new Point2D(this.x * factor, this.y * factor);
        }

        @Override
        public String toString() {
            return String.format("(%.2f, %.2f)", x, y);
        }
    }

    // 温度转换
    public static class TemperatureConverter {
        public static float celsiusToFahrenheit(float celsius) {
            return celsius * 9.0f / 5.0f + 32.0f;
        }

        public static float fahrenheitToCelsius(float fahrenheit) {
            return (fahrenheit - 32.0f) * 5.0f / 9.0f;
        }

        public static float celsiusToKelvin(float celsius) {
            return celsius + 273.15f;
        }

        public static float kelvinToCelsius(float kelvin) {
            return kelvin - 273.15f;
        }
    }

    // 物理计算
    public static class Physics {
        private static final float GRAVITY = 9.81f; // m/s²

        // 自由落体距离
        public static float freefall(float time) {
            return 0.5f * GRAVITY * time * time;
        }

        // 抛物线运动
        public static Point2D projectile(float velocity, float angle, float time) {
            float vx = velocity * (float) Math.cos(Math.toRadians(angle));
            float vy = velocity * (float) Math.sin(Math.toRadians(angle));

            float x = vx * time;
            float y = vy * time - 0.5f * GRAVITY * time * time;

            return new Point2D(x, y);
        }
    }

    // 金融计算
    public static class Finance {
        // 简单利息
        public static float simpleInterest(float principal, float rate, float time) {
            return principal * rate * time / 100.0f;
        }

        // 复合利息
        public static float compoundInterest(float principal, float rate, float time, int periods) {
            float r = rate / 100.0f / periods;
            return principal * (float) Math.pow(1 + r, periods * time) - principal;
        }

        // 贷款月供
        public static float monthlyPayment(float principal, float annualRate, int years) {
            float monthlyRate = annualRate / 100.0f / 12.0f;
            int months = years * 12;

            if (monthlyRate == 0) {
                return principal / months;
            }

            return principal * monthlyRate * (float) Math.pow(1 + monthlyRate, months) /
                   ((float) Math.pow(1 + monthlyRate, months) - 1);
        }
    }

    public static void main(String[] args) {
        System.out.println("=== 2D图形计算 ===");
        Point2D p1 = new Point2D(1.0f, 2.0f);
        Point2D p2 = new Point2D(4.0f, 6.0f);

        System.out.println("点1: " + p1);
        System.out.println("点2: " + p2);
        System.out.println("距离: " + String.format("%.2f", p1.distanceTo(p2)));
        System.out.println("相加: " + p1.add(p2));
        System.out.println("点1缩放2倍: " + p1.scale(2.0f));

        System.out.println("\n=== 温度转换 ===");
        float celsius = 25.0f;
        System.out.println(celsius + "°C = " + 
                          String.format("%.1f", TemperatureConverter.celsiusToFahrenheit(celsius)) + "°F");
        System.out.println(celsius + "°C = " + 
                          String.format("%.2f", TemperatureConverter.celsiusToKelvin(celsius)) + "K");

        System.out.println("\n=== 物理计算 ===");
        float time = 2.0f;
        System.out.println("自由落体 " + time + " 秒距离: " + 
                          String.format("%.2f", Physics.freefall(time)) + " 米");

        Point2D position = Physics.projectile(20.0f, 45.0f, 1.5f);
        System.out.println("抛物线运动1.5秒后位置: " + position);

        System.out.println("\n=== 金融计算 ===");
        float principal = 10000.0f;
        float rate = 5.0f;
        float years = 2.0f;

        float simple = Finance.simpleInterest(principal, rate, years);
        float compound = Finance.compoundInterest(principal, rate, years, 12);
        float monthly = Finance.monthlyPayment(principal, rate, (int)years);

        System.out.println("本金: " + String.format("%.2f", principal));
        System.out.println("简单利息: " + String.format("%.2f", simple));
        System.out.println("复合利息: " + String.format("%.2f", compound));
        System.out.println("月供: " + String.format("%.2f", monthly));
    }
}

精度和性能

public class FloatPrecisionPerformanceExample {

    // 精度测试
    public static void precisionTest() {
        System.out.println("=== 精度测试 ===");

        // float vs double 精度比较
        float f = 1.0f / 3.0f;
        double d = 1.0 / 3.0;

        System.out.println("float 1/3: " + f);
        System.out.println("double 1/3: " + d);

        // 累积误差
        float sum1 = 0.0f;
        for (int i = 0; i < 1000000; i++) {
            sum1 += 0.1f;
        }
        System.out.println("float累加0.1一百万次: " + sum1);
        System.out.println("预期结果: " + 100000.0f);
        System.out.println("误差: " + Math.abs(sum1 - 100000.0f));

        // 大数加小数的精度问题
        float large = 1e7f;
        float small = 1.0f;
        float result = large + small;

        System.out.println("大数 + 小数:");
        System.out.println(large + " + " + small + " = " + result);
        System.out.println("结果 - 大数 = " + (result - large));
        System.out.println("是否等于小数: " + ((result - large) == small));
    }

    // 性能测试
    public static void performanceTest() {
        System.out.println("\n=== 性能测试 ===");

        int iterations = 10_000_000;

        // float运算性能
        long startTime = System.nanoTime();
        float result1 = 0.0f;
        for (int i = 0; i < iterations; i++) {
            result1 += Math.sin(i) * Math.cos(i);
        }
        long floatTime = System.nanoTime() - startTime;

        // double运算性能
        startTime = System.nanoTime();
        double result2 = 0.0;
        for (int i = 0; i < iterations; i++) {
            result2 += Math.sin(i) * Math.cos(i);
        }
        long doubleTime = System.nanoTime() - startTime;

        System.out.println("float运算时间: " + floatTime / 1_000_000 + " ms");
        System.out.println("double运算时间: " + doubleTime / 1_000_000 + " ms");
        System.out.println("float结果: " + result1);
        System.out.println("double结果: " + result2);

        // 内存使用比较
        float[] floatArray = new float[1_000_000];
        double[] doubleArray = new double[1_000_000];

        System.out.println("float数组内存: " + (floatArray.length * 4) / 1024 + " KB");
        System.out.println("double数组内存: " + (doubleArray.length * 8) / 1024 + " KB");
    }

    public static void main(String[] args) {
        precisionTest();
        performanceTest();
    }
}

最佳实践

import java.math.BigDecimal;
import java.text.DecimalFormat;

public class FloatBestPractices {

    // 1. 安全的浮点数比较
    public static boolean floatEquals(float a, float b, float epsilon) {
        return Math.abs(a - b) < epsilon;
    }

    public static boolean floatEquals(float a, float b) {
        return floatEquals(a, b, 1e-6f); // 默认精度
    }

    // 2. 货币计算应避免使用float
    public static void currencyCalculation() {
        // 错误的做法
        float price1 = 0.1f;
        float price2 = 0.2f;
        float total = price1 + price2;
        System.out.println("错误的货币计算: " + total); // 可能不等于0.3

        // 正确的做法:使用BigDecimal
        BigDecimal bd1 = new BigDecimal("0.1");
        BigDecimal bd2 = new BigDecimal("0.2");
        BigDecimal bdTotal = bd1.add(bd2);
        System.out.println("正确的货币计算: " + bdTotal);
    }

    // 3. 格式化输出
    public static void formatFloat(float value) {
        DecimalFormat df = new DecimalFormat("#.##");
        System.out.println("保留2位小数: " + df.format(value));

        System.out.printf("printf格式化: %.2f%n", value);
        System.out.println("String.format: " + String.format("%.3f", value));
    }

    // 4. 边界值检查
    public static boolean isValidFloat(float value) {
        return Float.isFinite(value) && !Float.isNaN(value);
    }

    // 5. 数组操作的最佳实践
    public static float safeArraySum(float[] array) {
        if (array == null || array.length == 0) {
            return 0.0f;
        }

        // 使用double累积以减少精度损失
        double sum = 0.0;
        for (float value : array) {
            if (isValidFloat(value)) {
                sum += value;
            }
        }

        return (float) sum;
    }

    // 6. 范围验证
    public static float clamp(float value, float min, float max) {
        if (Float.isNaN(value)) {
            return min;
        }
        return Math.max(min, Math.min(max, value));
    }

    public static void main(String[] args) {
        System.out.println("=== 浮点数比较 ===");
        float a = 0.1f + 0.2f;
        float b = 0.3f;

        System.out.println("直接比较: " + (a == b));
        System.out.println("安全比较: " + floatEquals(a, b));

        System.out.println("\n=== 货币计算 ===");
        currencyCalculation();

        System.out.println("\n=== 格式化输出 ===");
        formatFloat(3.14159f);

        System.out.println("\n=== 数组求和 ===");
        float[] testArray = {1.1f, 2.2f, 3.3f, Float.NaN, 4.4f};
        System.out.println("安全求和: " + safeArraySum(testArray));

        System.out.println("\n=== 范围限制 ===");
        System.out.println("clamp(5.5f, 1.0f, 10.0f): " + clamp(5.5f, 1.0f, 10.0f));
        System.out.println("clamp(15.0f, 1.0f, 10.0f): " + clamp(15.0f, 1.0f, 10.0f));
        System.out.println("clamp(NaN, 1.0f, 10.0f): " + clamp(Float.NaN, 1.0f, 10.0f));
    }
}

float类型适用于对精度要求不高但需要节省内存的场景,如图形渲染、科学计算等。对于金融计算建议使用BigDecimal。

powered by Gitbook© 2025 编外计划 | 最后修改: 2025-07-28 16:25:54

results matching ""

    No results matching ""