C++ 将浮点转换为双精度浮点
将C++ 将浮点转换为双精度浮点,c++,floating-point,double,C++,Floating Point,Double,将浮点转换为双精度的成本有多高?它是否与int到long的转换一样简单 编辑:我假设一个平台,其中float是4字节,double是8字节,可能比将int转换为long要慢一些,因为需要的内存更大,操作更复杂。关于< p>的一个很好的参考,这是针对你正在使用的C++实现。在C++中,默认浮点类型是双浮点类型。编译器应针对以下代码发出警告: float a = 3.45; 因为将双精度值3.45指定给浮点。如果需要特别使用float,请在值后面加上f: 问题是,默认情况下,所有浮点数都是双精度的
浮点
转换为双精度
的成本有多高?它是否与int
到long
的转换一样简单
编辑:我假设一个平台,其中float是4字节,double是8字节,可能比将int转换为long要慢一些,因为需要的内存更大,操作更复杂。关于< p>的一个很好的参考,这是针对你正在使用的C++实现。在C++中,默认浮点类型是双浮点类型。编译器应针对以下代码发出警告:
float a = 3.45;
因为将双精度值3.45指定给浮点。如果需要特别使用float,请在值后面加上f:
问题是,默认情况下,所有浮点数都是双精度的。如果您不确定编译器的实现细节,并且对浮点计算没有深入的了解,那么坚持使用此默认值是安全的。避开演员阵容
另请参见。平台注意事项第4.5节
这取决于用于浮点计算的平台。对于x87 FPU,转换是免费的,因为寄存器内容是相同的-有时您可能支付的唯一价格是内存流量,但在许多情况下甚至没有流量,因为您可以简单地使用值而不进行任何转换。在这方面,x87实际上是一头怪兽——很难正确区分它上面的浮点和双精度,因为使用的指令和寄存器是相同的,不同的是加载/存储指令,而计算精度本身是使用状态位控制的。使用混合浮点/双精度计算可能会导致意外结果(因此有编译器命令行选项来控制精确行为和优化策略)
当您使用SSE(有时VisualStudio默认使用SSE)时,可能会有所不同,因为您可能需要在FPU寄存器中传输值,或者执行一些显式操作来执行转换
内存节省性能
作为总结,并回答您在其他地方的评论:如果您想将浮点计算的结果存储到32b存储器中,结果的速度将相同或更快,因为:
- 如果在x87上执行此操作,则转换是免费的-唯一的区别是将使用fstp dword[]而不是fstp qword[]
- 如果在启用SSE的情况下执行此操作,您甚至可能会看到一些性能提升,因为一旦计算精度仅为浮点而不是默认的双精度,就可以使用SSE进行一些浮点计算
- 在所有情况下,内存流量都较低
- 我无法想象它会变得太复杂。将int转换为long和将float转换为double的最大区别在于int类型有两个组件(符号和值),而浮点数有三个组件(符号、尾数和指数)
IEEE 754单精度编码
在32位中,使用1位作为符号,8
位表示指数,23位表示指数
意义。但是,它使用了
隐藏位,因此有效位为24
位(p=24),即使是
仅使用23位进行编码
--大卫·戈德伯格
因此,在float和double之间转换将保持相同的符号位,将float尾数的最后23/24位设置为double尾数,并将float指数的最后8位设置为double指数
这种行为甚至可以由……来保证。。。我还没有检查它,所以我不确定。浮点到双精度的转换在某些平台上是免费的(PPC,x86,如果您的编译器/运行时使用“不管您告诉我使用什么类型,我都将使用长双精度,nyah-nyah”求值模式) 在x86环境中,浮点计算实际上是使用SSE寄存器在指定类型中进行的,浮点和双精度之间的转换与浮点加法或乘法的转换一样昂贵(即,除非您进行了大量转换,否则不太可能成为性能考虑因素) 在缺乏硬件浮点的嵌入式环境中,它们的成本可能会有点高。也许这有助于:
#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;
}
#包括
#包括
#包括
双浮点数(浮点值)
{
char-czDummy[30];
printf(czDummy,“%9.5f”,fValue);
双D值=strtod(czDummy,NULL);
返回数据值;
}
int main(int argc,char*argv[])
{
浮动Fv值(250.84f);
双D值=_ftod(fValue);//良好的转换
双dValue2=fValue;//转换错误
printf(“%f\n”,dValue);//250.840000
printf(“%f\n”,dValue2);//250.839996
getch();
返回0;
}
您的探查器是否指示您的程序在将浮点转换为双倍时陷入困境?请指定平台。这是x86(Win32)还是x64(Win32)上的Windows?或者PPC,或者是一些嵌入式平台?在不了解平台的情况下,这个问题是无法回答的。我需要存储大量浮点值,不需要双精度,并且希望将所需内存减半。@Jen:正如我所说的,这不是语言问题,而是编译器+浮点算术实现问题。您需要查看编译器+硬件手册。这根本不能回答这个问题。@Justicle也没有人回答!这是一个特定于平台的问题。至少,向提出问题的人解释为什么你的代码片段实际上是问题的答案会让你的答案在某种程度上被接受
#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;
}