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。