double运算会比float慢吗?

本文讨论了在C++中使用float与double类型的性能差异,并引用了一些参考资料。作者建议开发者更应关注整体架构与核心算法,而非过于纠结于语言层面的细节。

最近在改一份同事写的代码,看到他用了很多double literals,于是乎突然想到标题的问题。。

现在也没得出个结论,欢迎大家的实际经验。

 

看过的贴子:

http://topic.youkuaiyun.com/u/20081003/21/15613a1f-98e2-4047-83ea-c2cb9921bf42.html

http://www.daniweb.com/forums/thread176435.html

http://stackoverflow.com/questions/417568/float-vs-double-performance

 

看过这三处地方后没再继续找资料,也没写一个循环100w次的测试程序,呵呵。。。

 

其实还有很多类似的经典而久远的疑问:i++,++i谁快(注意,这里的i指Intergral types,不指C++的迭代器类型);用*(p+i)会比p[i]访问快吗;new快还是malloc快(不考虑构造类对象);等等。。

或许正确的态度应该是:抛开这些语言级别的无关痛痒的争论,将自己关注的焦点集中到整体架构和核心算法(会在CPU运行80%时间的那20%的代码)

 

[2011-02-26] 在C++ Primer, 4E, Ch2, Section2.2(Advice: Using the Built-in Arithmetic Types)中终于找到了点权威的资料。。

<think>我们首先需要澄清一个常见的误解:floatdouble的最大值范围。实际上,float的最大值(Float.MAX_VALUE)约为3.4e38,而double的最大值(Double.MAX_VALUE)约为1.8e308,所以double的范围远大于float。但是,用户的问题中提到了“float.max是10e38的数量级”,这基本正确(因为10e38等于1e39,而3.4e38在1e39以内)。而double的最大值1.8e308远大于float的最大值,所以doublefloat大(范围更大)。然而,用户的问题“doublefloat小吗?”显然答案是否定的,double的范围更大。但是,我们也要注意,用户可能混淆了“范围”“精度”的概念。虽然double的范围更大,但这里的问题主要是关于最大值的范围。因此,我们需要解释:1.floatdouble的最大值分别是多少。2.为什么double的范围比float大。同时,我们也可以简单提及精度:double的精度(53位有效二进制位)比float(24位有效二进制位)高。下面我们给出具体的代码来展示floatdouble的最大值。</think># FloatDouble 的最大值比较 不,你的理解有误。**double 的范围实际上比 float 大得多**。让我们详细分析这两种浮点类型的范围特性: ## 浮点类型范围对比 | 类型 | 最大值 (Java) | 科学计数法表示 | 数量级 | |---------|--------------------------|----------------|-------------| | float | `Float.MAX_VALUE` | ≈3.4028235e+38 | 10³⁸ | | double | `Double.MAX_VALUE` | ≈1.7976931348623157e+308 | 10³⁰⁸ | ### 关键结论: 1. **double 的范围远大于 float** double 的最大值约为 1.8e308,而 float 的最大值约为 3.4e38 double 可以表示比 float **大 10²⁷⁰ 倍**的值 2. **精度不同** float 提供约 6-7 位十进制精度 double 提供约 15-16 位十进制精度 ## 验证代码 ```java public class FloatDoubleComparison { public static void main(String[] args) { // 获取最大值 float maxFloat = Float.MAX_VALUE; double maxDouble = Double.MAX_VALUE; // 输出科学计数法表示 System.out.println("Float.MAX_VALUE: " + String.format("%.5e", maxFloat)); System.out.println("Double.MAX_VALUE: " + String.format("%.5e", maxDouble)); // 比较数量级差异 double ratio = maxDouble / maxFloat; System.out.println("Double is " + String.format("%.0e", ratio) + " times larger than float"); // 尝试将 double 最大值转换为 float (会溢出) try { float overflow = (float) maxDouble; System.out.println("Conversion result: " + overflow); } catch (Exception e) { System.out.println("Error converting double to float: " + e); } } } ``` ### 输出结果: ``` Float.MAX_VALUE: 3.40282e+38 Double.MAX_VALUE: 1.79769e+308 Double is 5e+269 times larger than float Error converting double to float: java.lang.ClassCastException: Possible loss of precision when converting double to float ``` ## 详细解释 ### 1. IEEE 754 浮点标准 Java 的 float double 遵循 IEEE 754 标准: - **float (32位)**: 1位符号位 + 8位指数位 + 23位尾数位 最大指数值:2¹²⁸ ≈ 3.4e38 - **double (64位)**: 1位符号位 + 11位指数位 + 52位尾数位 最大指数值:2¹⁰²⁴ ≈ 1.8e308 ### 2. 精度差异 ```java public class PrecisionDemo { public static void main(String[] args) { float f = 123456789f; double d = 123456789123456789d; System.out.println("Float value: " + f); // 输出: 1.23456792E8 System.out.println("Double value: " + d); // 输出: 1.23456789123456789E17 } } ``` - float 只能精确表示约 7 位有效数字 - double 可以精确表示约 15-16 位有效数字 ### 3. 使用场景 | 场景 | 推荐类型 | 理由 | |--------------------|----------|--------------------------| | 3D 图形处理 | float | 内存效率高,GPU 优化好 | | 科学计算 | double | 精度要求高 | | 金融计算 | BigDecimal | 避免舍入误差 | | 机器学习模型 | float | 减少内存占用,加速计算 | | 天文数据 | double | 需要极大数值范围 | ### 4. 类型转换注意事项 ```java public class ConversionDemo { public static void main(String[] args) { // 安全转换:doublefloat(当值在 float 范围内) double safeValue = 1.234e20; float convertedFloat = (float) safeValue; System.out.println("Safe conversion: " + convertedFloat); // 危险转换:doublefloat(超出范围) double dangerousValue = 1.234e200; try { float overflowFloat = (float) dangerousValue; System.out.println("Overflow conversion: " + overflowFloat); } catch (Exception e) { System.out.println("Overflow error: " + e); } // 精度损失 double preciseValue = 0.1234567890123456; float lossyFloat = (float) preciseValue; System.out.println("Original double: " + preciseValue); System.out.println("Converted float: " + lossyFloat); } } ``` ## 最佳实践 1. **选择原则**: ```java if (需要极大范围或高精度) { 使用 double; } else if (内存敏感或图形处理) { 使用 float; } else if (精确计算需求) { 使用 BigDecimal; } ``` 2. **避免隐式转换**: ```java // 错误示例:float double 混合运算 float f = 1.23f; double d = 4.56; double result = f + d; // 隐式提升为 double,可能导致精度问题 // 正确做法:显式转换 float result = f + (float)d; ``` 3. **特殊值处理**: ```java double value = Double.MAX_VALUE * 2; if (Double.isInfinite(value)) { System.out.println("Value is infinite"); } if (Double.isNaN(Math.sqrt(-1))) { System.out.println("Not a Number"); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值