我读过关于双精度和单精度之间的区别。然而,在大多数情况下,float和double似乎是可互换的,即使用其中一个似乎不会影响结果。事实真的如此吗?什么时候浮点数和双精度数可以互换?它们之间有什么区别?
当前回答
浮点数的精度比双精度数低。虽然你已经知道了,但为了更好地理解,请阅读《关于浮点算术我们应该知道什么》。
其他回答
如果使用嵌入式处理,最终底层硬件(例如FPGA或某些特定的处理器/微控制器模型)将在硬件中优化实现float,而double将使用软件例程。因此,如果浮点数的精度足以满足需求,则使用浮点数执行程序的速度将比使用浮点数执行程序的速度快几倍。正如在其他答案中提到的,要小心累积错误。
与整型(整数)不同,浮点数有小数点,双精度浮点数也有。 但两者之间的区别在于,double类型的细节是float类型的两倍,这意味着它的小数点后的数字可以是小数点后的两倍。
巨大的差异。
顾名思义,double的精度是浮点数[1]的2倍。一般来说,double有15个十进制数字的精度,而float有7个。
下面是如何计算位数的:
Double有52个尾数位+ 1个隐藏位:log(253)÷log(10) = 15.95位 浮点数有23个尾数位+ 1个隐藏位:log(224)÷log(10) = 7.22位数字
当重复计算时,这种精度损失可能导致更大的截断误差累积。
float a = 1.f / 81;
float b = 0;
for (int i = 0; i < 729; ++ i)
b += a;
printf("%.7g\n", b); // prints 9.000023
而
double a = 1.0 / 81;
double b = 0;
for (int i = 0; i < 729; ++ i)
b += a;
printf("%.15g\n", b); // prints 8.99999999999996
同样,float的最大值约为3e38,但double约为1.7e308,因此对于一些简单的事情,使用float可以比double更容易达到“无穷大”(即一个特殊的浮点数),例如计算60的阶乘。
在测试期间,可能有一些测试用例包含这些巨大的数字,如果使用浮点数,可能会导致程序失败。
当然,有时,即使是双精度也不够精确,因此我们有时会有长双精度[1](上面的例子在Mac上给出了9.000000000000000066),但所有浮点类型都有四舍五入错误,所以如果精度非常重要(例如货币处理),你应该使用int或分数类。
此外,不要使用+=对大量浮点数求和,因为错误很快就会累积起来。如果使用Python,请使用fsum。否则,尝试实现Kahan求和算法。
[1]: C和c++标准没有指定float、double和long double的表示方式。这三种方法都有可能实现为IEEE双精度。然而,对于大多数架构(gcc, MSVC;x86, x64, ARM) float确实是IEEE单精度浮点数(binary32), double是IEEE双精度浮点数(binary64)。
使用浮点数时,您不能相信本地测试与在服务器端执行的测试完全相同。在本地系统和运行最终测试的地方,环境和编译器可能不同。我以前在一些TopCoder比赛中看到过这个问题很多次,特别是当你试图比较两个浮点数时。
内置比较操作的不同之处在于,当你用浮点数比较两个数字时,数据类型的差异(即浮点数或双精度数)可能会导致不同的结果。