我很难理解为什么这段代码会导致3f000000
。
float f = 5e-1;
printf("%x", *(int*)&f);
答案 0 :(得分:9)
这是未定义的行为:标准不保证指向int
和float
的指针具有相同的对齐方式,因此(int*)&f
强制转换无效(Q&A)。< / p>
在您的情况下,演员表生成的值与下面的0.5(5e-1)的IEEE-754表示一致:
bin: 0011 1111 0000 0000 0000 0000 0000 0000
+--- ---- -=== ==== ==== ==== ==== ====
hex: 3 f 0 0 0 0 0 0
其中+
是符号位,-
是指数位,=
是尾数位。
但是,当您在其他系统上运行相同的程序时,或者即使该程序将运行完成,也绝对无法保证同一程序会产生相同的结果。
答案 1 :(得分:5)
您可能更喜欢
void dump(const void *data, size_t len) {
const unsigned char *x = data;
printf("%02x", x[0]);
for (size_t k = 1; k < len, k++) printf(" %02x", x[k]);
puts("");
}
然后
float f = 5e-1;
dump(&f, sizeof f);
答案 2 :(得分:2)
由于(int*)&f
,您的代码行为未定义。由于类型不相关,C风格的演员表无效。
如果要检查与f
关联的内存,则C和C ++都允许转换为const unsigned char*
,并使用指针算法跟踪内存到sizeof(f)
。
答案 3 :(得分:2)
由于您不熟悉C / C++
- 我猜 - 您可能对undefined behaviors
没有任何想法。简而言之,C / C++
语言有些角落不会define
应该发生什么。为什么?背后有很多原因,例如性能。在这些情况下,行为的结果或效果完全依赖于实现(编译器 - 更具体地说(例如gcc,vc ++))。
您在此处所做的工作列于What are all the common undefined behaviours that a C++ programmer should know about?
的已接受答案的第7项答案 4 :(得分:2)
其他人已经解决了未定义的行为,所以我只会解决这个问题:
我很难理解为什么这段代码导致3f000000
代码尝试打印浮点值0.5(或5e-1)的二进制表示。
(它以非法方式执行此操作 - 请参阅其他答案以了解正确方法 - 请参阅此答案https://stackoverflow.com/a/45036945/4386427)
值3f000000的解释是您的系统似乎使用IEEE 754单精度二进制浮点格式(请参阅https://en.wikipedia.org/wiki/Single-precision_floating-point_format)。
格式使用
所以在你的情况下
通常,该值计算如下:
value =( - 1)^ sign *(1 + fraction)* 2 ^(exponent - 127)
由于sign和fraction为0,因此很容易计算出值:
值= 1 * 1 * 2 ^(126 - 127)= 2 ^ -1 = 0.5
因此,对于IEEE 754单精度二进制浮点,值为0.5的浮点数与二进制模式3f000000一起存储