我必须打印一个二进制表示形式(从内存中)为float / double。尽管它对于整数非常有效,但对于一些浮点数,我却表现出奇怪的行为。
我的意思是,3.14和21.37的结果相同(两倍)。对于8.5,我得到0。
21.37的两倍:
0101000111101011100001010001111101010001111010111000010100011111
3.14的两倍:
0101000111101011100001010001111101010001111010111000010100011111
8.5的两倍:
0000000000000000000000000000000000000000000000000000000000000000000000000000
#include <stdio.h>
int printBit(int c, int i) {
return (c & (1 << (i - 1))) ? 1 : 0;
}
int main()
{
double f;
int *b;
scanf("%lf", &f);
b = &f;
int i;
printf("Jako double: \n");
for (i = sizeof(f) * 8; i > 0; i--)
{
printf("%i", printBit(*b, i));
}
printf("\n");
}
语句b = &f;
违反了严格别名,因此在取消引用b
时,程序的行为未定义。
绕过这个问题的一种好方法是通过强制转换为const unsigned char*
来读取内存(这是严格的别名规则的例外),并对该指针使用指针算法,直到达到原始类型的sizeof
为止。