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


当前回答

如果使用嵌入式处理,最终底层硬件(例如FPGA或某些特定的处理器/微控制器模型)将在硬件中优化实现float,而double将使用软件例程。因此,如果浮点数的精度足以满足需求,则使用浮点数执行程序的速度将比使用浮点数执行程序的速度快几倍。正如在其他答案中提到的,要小心累积错误。

其他回答

给定二次方程:x2−4.0000000 x + 3.9999999 = 0, 10位有效数字的精确根为:r1 = 2.000316228, r2 = 1.999683772。

使用float和double,我们可以编写一个测试程序:

#include <stdio.h>
#include <math.h>

void dbl_solve(double a, double b, double c)
{
    double d = b*b - 4.0*a*c;
    double sd = sqrt(d);
    double r1 = (-b + sd) / (2.0*a);
    double r2 = (-b - sd) / (2.0*a);
    printf("%.5f\t%.5f\n", r1, r2);
}

void flt_solve(float a, float b, float c)
{
    float d = b*b - 4.0f*a*c;
    float sd = sqrtf(d);
    float r1 = (-b + sd) / (2.0f*a);
    float r2 = (-b - sd) / (2.0f*a);
    printf("%.5f\t%.5f\n", r1, r2);
}   

int main(void)
{
    float fa = 1.0f;
    float fb = -4.0000000f;
    float fc = 3.9999999f;
    double da = 1.0;
    double db = -4.0000000;
    double dc = 3.9999999;
    flt_solve(fa, fb, fc);
    dbl_solve(da, db, dc);
    return 0;
}  

运行程序得到:

2.00000 2.00000
2.00032 1.99968

注意,这些数字并不大,但是使用float仍然可以得到抵消效果。

(事实上,上面的方法并不是用单精度浮点数或双精度浮点数求解二次方程的最佳方法,但即使使用更稳定的方法,答案也不会改变。)

双精度为64,单精度为64 (float)是32位。 double有一个更大的尾数(实数的整数位)。 任何不准确的地方都将在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,就可以省去很多麻烦和类型转换。

浮点数的精度比双精度数低。虽然你已经知道了,但为了更好地理解,请阅读《关于浮点算术我们应该知道什么》。

有三种浮点类型:

浮动 双 长两倍

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