用c ++实验

时间:2010-11-14 16:41:45

标签: c++ floating-point

我测试了以下代码

#include <iostream>
#include <cmath>
#include <cfloat>
#include <typeinfo>
using namespace std;
int main(){
 int n=2;
 float f=23.01;
 int *ptr=(int *) (&f);
 *ptr<<=n;
 cout<<*ptr<<endl;



  return 0;
}

因为我知道在c ++中不允许对浮点类型数进行逐位运算我试图将这些数转换为整数类型然后执行右移 我得到的结果是

115364332

是对的吗?感谢

2 个答案:

答案 0 :(得分:3)

此示例中没有“正确”。通过将指向float的指针转换为指向int的指针然后尝试使用结果,您已调用未定义的行为。如果要对浮点数进行“位移”,则可以将每个位乘以2。没有必要采取这种黑客行为。

答案 1 :(得分:2)

在这种情况下,您将float表示的字节视为int字节,并且在使用指针时违反了C ++的strict aliasing rules

但如果您想知道如果您将float下面的字节视为int,然后对这些字节执行了2位左移......

以下代码示例在C中(但在C ++中有效),我将float(假设IEEE-754 representation)的字节复制到unsigned int,然后执行bitshift在它上面。

编辑更新的代码段,以显示执行int位移的情况后发生的后果,然后再尝试将这些字节用作float个字节。

编辑好奇:编译并在Windows 7中的Visual Studio 2008上运行,在Debian Linux中使用GCC 4.4在英特尔系统上运行

#include <stdio.h>
#include <string.h>

int main()
{
   float f = 23.01;

   unsigned int ui;
   memcpy(&ui, &f, sizeof(ui));

   printf("hex is %x\n", ui);

   ui <<= 2;

   printf("%d is the new value of ui\n", ui );

   printf("hex of ui now is %x\n", ui);

   float newf;
   memcpy(&newf, &ui, sizeof(newf));

   printf("%f is newf\n", newf);

   /* yes this is violating the strict aliasing rules, but just for show */
   printf("%d is newf's int representation\n", *((unsigned int*)&newf));

   return 0;
}


/** Output
birryree@lilun:~$ gcc hexout.c
birryree@lilun:~$ ./a.out
hex is 41b8147b
115364332 is the new value of ui
hex of ui now is 6e051ec
0.000000 is newf
115364332 is newf's int representation
**/

正如DeadMG所说......不要这样做。