改装一次要多少钱 float 到一个 double?它像一个微不足道的 intlong 转换?

编辑:我假设一个平台,其中 float 为 4 字节,double 为 8 字节

有帮助吗?

解决方案

平台注意事项

这取决于用于浮点计算的平台。对于 x87 FPU,转换是免费的,因为寄存器内容是相同的 - 有时您可能付出的唯一代价是内存流量,但在许多情况下甚至没有流量,因为您可以简单地使用该值而不进行任何转换。x87 在这方面实际上是一个奇怪的野兽 - 很难正确区分浮点型和双精度型,因为使用的指令和寄存器是相同的,不同的是加载/存储指令和计算精度本身是使用状态位控制的。使用混合浮点/双精度计算可能会导致意外结果(因此有编译器命令行选项来控制确切的行为和优化策略)。

当您使用 SSE 时(有时 Visual Studio 默认使用 SSE),情况可能会有所不同,因为您可能需要传输 FPU 寄存器中的值或执行某些显式操作来执行转换。

内存节省性能

作为总结,并回答您在其他地方的评论:如果要将浮点计算的结果存储到 32b 存储中,结果将具有相同的速度或更快,因为:

  • 如果您在 x87 上执行此操作,则转换是免费的 - 唯一的区别是将使用 fstp dword[] 而不是 fstp qword[]。
  • 如果在启用 SSE 的情况下执行此操作,您甚至可能会看到一些性能提升,因为一旦计算精度仅为浮点而不是默认的双精度,就可以使用 SSE 完成一些浮点计算。
  • 在所有情况下,内存流量都较低

其他提示

在某些平台上浮动到双重转换是免费的(PPC,x86,如果你的编译器/运行时使用了“告诉我使用什么类型的地狱”,我将以长双重评估所有内容,nyah nyah“评估模式”。

在使用SSE寄存器在指定类型中实际进行浮点计算的x86环境中,float和double之间的转换与浮点加法或乘法一样昂贵(即,不太可能是性能考虑因素,除非你正在做很多)。

在缺乏硬件浮点的嵌入式环境中,它们可能有点昂贵。

这特定于您正在使用的C ++实现。在C ++中,默认浮点类型是 double 。编译器应该为以下代码发出警告:

float a = 3.45;

因为双值3.45被分配给浮点数。如果您需要专门使用浮点数,请使用 f

后缀该值
float a = 3.45f;

关键是,所有浮点数默认为 double 。如果您不确定编译器的实现细节并且不了解浮点计算,那么坚持这个默认值是安全的。避免演员。

另见 C ++编程语言第4.5节。

我无法想象它会变得更加复杂。将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 甚至可以保证这种行为......我还没有检查了一下,所以我不确定。

可能比将int转换为long要慢一些,因为所需的内存更大,操作更复杂。关于内存对齐问题的一个很好的参考资料

也许这有帮助:

#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;
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top