将int转换为float:如何完成

时间:2012-07-20 15:14:01

标签: c++ c casting type-conversion

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

整数我在这里是浮动然后f(不知何故)成功代表5.0:

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

但是,如果我们尝试这种方法:

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

f不会得到5.0,因为它以“float的方式”解释存储在i中的位。那么编译器在第一种情况下实际上做了多少魔术呢?这似乎是一项非常努力的工作......有人可以指明吗?感谢。

7 个答案:

答案 0 :(得分:13)

这是一项努力工作,但任何具有浮点支持的CPU都会提供执行它的指令。

如果您必须为自己将2的补码int转换为IEEE浮动格式,您会:

  • 取整数base-2 log(与最高设置位的索引密切相关),它给出了指数。将其偏移并将其存储在浮点数的指数位中。
  • 复制int的顶部n位(从第一个设置的非符号位后的位开始)到float的有效位数。然而,nfloat(32位单精度浮点数为23)中有很多有效位。如果int中有任何剩余的位(即,如果它大于2 24 ),并且在你有空间的那一位之后的下一位是1,根据运行中的IEEE舍入模式,您可能会或可能不会进行舍入。
  • 将符号位从int复制到float

答案 1 :(得分:6)

如果你看看程序集

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

fild 是神奇的

答案 2 :(得分:2)

在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

答案 3 :(得分:2)

将int位转换为float

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;
}

答案 4 :(得分:1)

魔力取决于你的平台。

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

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

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

[sIIIIFFFF]

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

 -  47.5000
[sIIII.FFFF]

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

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

与此示例中一样,商品C ++实现使用通常称为IEEE Floating Point的浮点表示,另请参阅IEEE 754-1985。这些比定点数字更复杂,因为它们确实指定了形式_s * m n 的简单公式,但是,它们具有明确定义的解释,你可以将它们展现得更合适。

答案 5 :(得分:0)

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

答案 6 :(得分:0)

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

   int i = 5;
00A613BE  mov         dword ptr [i],5 

   float f = i;
00A613C5  fild        dword ptr [i] 
00A613C8  fstp        dword ptr [f]