将int转换为float:如何完成

Convert int to float: how it is done

本文关键字:何完成 float int 转换      更新时间:2023-10-16

我是C编程语言的新手,我想问一个问题。

这里的整数i是浮点型,然后f(不知何故)成功地表示5.0:

int i = 5;
float f = i;   //Something happened here...

然而,如果我们尝试这种方法:

int i = 5;
float f = *(float *)&i;

f不会得到5.0,因为它以"float的方式"解释存储在i中的位。那么,在第一种情况下,编译器到底有什么魔力呢?这似乎是一项相当艰巨的工作。。。有人能具体说明吗?谢谢

这是一项耗时的工作,但任何支持浮点运算的CPU都会提供一条指令。

如果您必须将2的补码int转换为IEEE浮点格式,您可以:

  • 取以2为基数的整数log(与最高设置位的索引密切相关),它会给出指数。偏移此值并将其存储在浮点的指数位中
  • 将int的顶部n位(从第一个设置的无符号位之后的位开始)复制到浮点的有效位。然而,nfloat中有效位的许多位(对于32位单精度浮点值为23)。如果int中有任何剩余的位(即,如果它大于224),并且在您有空间的位之后的下一个位是1,则您可以四舍五入,也可以不四舍五进,这取决于操作中的IEEE四舍五五入模式
  • 将符号位从CCD_ 7复制到CCD_

如果您查看组装

    int i = 5;
000D139E  mov         dword ptr [i],5  
    float f = i;
000D13A5  fild        dword ptr [i]  
000D13A8  fstp        dword ptr [f]  

filt是什么神奇的

将int位转换为浮动

float IntBitsToFloat(long long int bits)
{
    int sign     = ((bits & 0x80000000) == 0) ? 1 : -1;
    int exponent = ((bits & 0x7f800000) >> 23);
    int mantissa =  (bits & 0x007fffff);
    mantissa |= 0x00800000;
   // Calculate the result:
   float f = (float)(sign * mantissa * Power(2, exponent-150));
   return f;
}

在IA32系统上,编译器将生成以下内容:-

fild dword ptr [i] ; load integer in FPU register, I believe all 32bit integers can be represented exactly in an FPU register
fstp dword ptr [f] ; store fpu register to RAM, truncating/rounding to 32 bits, so the value may not be the same as i

魔术取决于您的平台。

一种可能性是,您的CPU有一条特殊的指令,可以将浮点数字复制到整数寄存器中。

当然,必须有人设计这些CPU,所以这并不是对现有算法的真正解释。

一个平台可能使用这样的浮点格式(实际上,为了示例起见,这是一种定点格式):

[sIIIIFFFF]

其中s是符号,Is是点之前的部分,Fs是点之后的部分,例如(点是虚拟的,仅用于表示)

 -  47.5000
[sIIII.FFFF]

在这种情况下,转换几乎是微不足道的,可以使用比特移位来实现:

    -47.5000
 >> 4
 ---------------
    -47

与本例一样,商品C++实现使用浮点表示,通常称为IEEE浮点,另请参阅IEEE 754-1985。这些比不定点数更复杂,因为它们确实指定了一个形式为_s*mn的简单公式,然而,它们有一个定义良好的解释,你可以将它们展开成更合适的东西。

好吧,我刚刚在VC++下编译了有问题的代码,并查看了反汇编:

   int i = 5;
00A613BE  mov         dword ptr [i],5 
   float f = i;
00A613C5  fild        dword ptr [i] 
00A613C8  fstp        dword ptr [f] 

第一个汇编语句将5移动到i表示的内存中。第二个语句filtd将i表示的存储器转换为浮点数,并将其推送到FPU堆栈上。第三条语句fstp获取FPU堆栈上的内存并将其移动到f。

在几乎所有现代系统中,浮点运算的规范都是IEEE754标准。这详细介绍了从内存中的布局到截断和舍入如何传播的所有内容。这是一个很大的领域,在科学和工程编程中经常需要详细考虑一些问题。