我读过关于双精度和单精度之间的区别。然而,在大多数情况下,float和double似乎是可互换的,即使用其中一个似乎不会影响结果。事实真的如此吗?什么时候浮点数和双精度数可以互换?它们之间有什么区别?


当前回答

有三种浮点类型:

浮动 双 长两倍

一个简单的维恩图可以解释: 类型值的集合

其他回答

float类型,长度为32位,精度为7位。虽然它可以存储非常大或非常小的范围(+/- 3.4 * 10^38或* 10^-38)的值,但它只有7位有效数字。

类型double, 64位长,具有更大的范围(*10^+/-308)和15位精度。

类型long double名义上是80位,尽管给定的编译器/操作系统配对可能会将其存储为12-16字节以进行对齐。长双精度数的指数大得离谱,应该有19位精度。微软以其无限的智慧,将long double限制为8字节,与普通double相同。

一般来说,当需要浮点值/变量时,只需使用double类型。默认情况下,表达式中使用的字面浮点值将被视为双精度值,并且大多数返回浮点值的数学函数都会返回双精度值。如果只使用double,就可以省去很多麻烦和类型转换。

在数量上,正如其他答案所指出的,不同之处在于double类型的精度是float类型的两倍,范围是float类型的三倍(取决于你如何计算)。

但也许更重要的是质的差异。float类型具有良好的精度,无论您正在做什么,这通常都足够好。另一方面,Type double具有出色的精度,无论你在做什么,它几乎总是足够好。

结果是,几乎总是应该使用类型double,这一点并不广为人知。除非你有一些特别的需要,否则你几乎不应该使用float类型。

As everyone knows, "roundoff error" is often a problem when you're doing floating-point work. Roundoff error can be subtle, and difficult to track down, and difficult to fix. Most programmers don't have the time or expertise to track down and fix numerical errors in floating-point algorithms — because unfortunately, the details end up being different for every different algorithm. But type double has enough precision such that, much of the time, you don't have to worry. You'll get good results anyway. With type float, on the other hand, alarming-looking issues with roundoff crop up all the time.

And the thing that's not necessarily different between type float and double is execution speed. On most of today's general-purpose processors, arithmetic operations on type float and double take more or less exactly the same amount of time. Everything's done in parallel, so you don't pay a speed penalty for the greater range and precision of type double. That's why it's safe to make the recommendation that you should almost never use type float: Using double shouldn't cost you anything in speed, and it shouldn't cost you much in space, and it will almost definitely pay off handsomely in freedom from precision and roundoff error woes.

(尽管如此,当你在微控制器上进行嵌入式工作或编写针对GPU优化的代码时,你可能需要float类型的“特殊需求”之一。在这些处理器上,double类型可能会非常慢,或者几乎不存在,所以在这种情况下,程序员通常会选择float类型来提高速度,并可能为精度付出代价。)

与整型(整数)不同,浮点数有小数点,双精度浮点数也有。 但两者之间的区别在于,double类型的细节是float类型的两倍,这意味着它的小数点后的数字可以是小数点后的两倍。

使用浮点数时,您不能相信本地测试与在服务器端执行的测试完全相同。在本地系统和运行最终测试的地方,环境和编译器可能不同。我以前在一些TopCoder比赛中看到过这个问题很多次,特别是当你试图比较两个浮点数时。

我刚刚遇到了一个错误,我花了很长时间才弄清楚,这可能会给你一个浮点精度的好例子。

#include <iostream>
#include <iomanip>

int main(){
  for(float t=0;t<1;t+=0.01){
     std::cout << std::fixed << std::setprecision(6) << t << std::endl;
  }
}

输出为

0.000000
0.010000
0.020000
0.030000
0.040000
0.050000
0.060000
0.070000
0.080000
0.090000
0.100000
0.110000
0.120000
0.130000
0.140000
0.150000
0.160000
0.170000
0.180000
0.190000
0.200000
0.210000
0.220000
0.230000
0.240000
0.250000
0.260000
0.270000
0.280000
0.290000
0.300000
0.310000
0.320000
0.330000
0.340000
0.350000
0.360000
0.370000
0.380000
0.390000
0.400000
0.410000
0.420000
0.430000
0.440000
0.450000
0.460000
0.470000
0.480000
0.490000
0.500000
0.510000
0.520000
0.530000
0.540000
0.550000
0.560000
0.570000
0.580000
0.590000
0.600000
0.610000
0.620000
0.630000
0.640000
0.650000
0.660000
0.670000
0.680000
0.690000
0.700000
0.710000
0.720000
0.730000
0.740000
0.750000
0.760000
0.770000
0.780000
0.790000
0.800000
0.810000
0.820000
0.830000
0.839999
0.849999
0.859999
0.869999
0.879999
0.889999
0.899999
0.909999
0.919999
0.929999
0.939999
0.949999
0.959999
0.969999
0.979999
0.989999
0.999999

正如你所看到的,在0.83之后,精度显著下降。

然而,如果我将t设为双倍,这样的问题就不会发生。

我花了五个小时才意识到这个小错误,它毁了我的程序。