将 float
转换为 double
有多昂贵?它是否像将 int
转换为 long
那样简单?
编辑:我假设平台上的 float
是 4 字节,double
是 8 字节。
将 float
转换为 double
有多昂贵?它是否像将 int
转换为 long
那样简单?
编辑:我假设平台上的 float
是 4 字节,double
是 8 字节。
这取决于用于浮点计算的平台。对于x87 FPU,转换是免费的,因为寄存器内容相同-您有时可能会付出的唯一代价是内存流量,但在许多情况下,甚至没有流量,因为您可以直接使用值而无需进行任何转换。就这方面而言,x87实际上是一种奇怪的生物-很难在它上面正确区分浮点数和双精度数,因为所使用的指令和寄存器相同,不同之处在于加载/存储指令和计算精度本身是使用状态位控制的。使用混合的浮点/双精度计算可能会导致意想不到的结果(并且由于这个原因,有编译器命令行选项来控制精确行为和优化策略)。
当您使用SSE(有时Visual Studio默认使用SSE)时,情况可能会有所不同,因为您可能需要在FPU寄存器中传输值或执行某些显式操作以执行转换。
总之,回答您在其他地方的评论:如果您希望将浮点计算的结果存储到32b存储中,则结果速度将相同或更快,因为:
在一些平台上(如PPC、x86),浮点数转换为双精度数可以免费进行(如果你的编译器/运行时采用“无论你告诉我使用什么类型,我都要将所有内容评估为long double”的评估模式)。
在使用SSE寄存器实际执行指定类型的浮点运算的x86环境中,float和double之间的转换与浮点加法或乘法一样昂贵(即,除非你需要进行大量此类操作,否则不太可能影响性能)。
在缺乏硬件浮点支持的嵌入式环境中,这些转换可能会比较昂贵。
我想象不出这会更加复杂。将int转换为long和将float转换为double之间的主要区别在于,int类型有两个组成部分(符号和值),而浮点数有三个组成部分(符号、尾数和指数)。
IEEE 754单精度使用32位编码,其中1位用于符号,8位用于指数,23位用于有效数字。但是,它使用了一个隐藏位,因此有效数字是24位(p = 24),即使只使用了23位进行编码。
-- David Goldberg, 计算机科学家应该了解的浮点运算知识
因此,将float转换为double将保持相同的符号位,将float的尾数的最后23/24位设置为double的尾数,并将float的指数的最后8位设置为double的指数。
这种行为甚至可能由IEEE 754保证...我没有检查过,所以不确定。
这个与你正在使用的C++实现有关。在C++中,默认的浮点类型是double。编译器应该为以下代码发出警告:
float a = 3.45;
因为将双精度值3.45赋给了浮点数。如果您需要特别使用浮点数,请在值后缀加上f:
float a = 3.45f;
或许这可以帮助:
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
double _ftod(float fValue)
{
char czDummy[30];
printf(czDummy,"%9.5f",fValue);
double dValue = strtod(czDummy,NULL);
return dValue;
}
int main(int argc, char* argv[])
{
float fValue(250.84f);
double dValue = _ftod(fValue);//good conversion
double dValue2 = fValue;//wrong conversion
printf("%f\n",dValue);//250.840000
printf("%f\n",dValue2);//250.839996
getch();
return 0;
}