[英]Printf() of a float as hexadecimal number
我很难理解为什么此代码会导致3f000000
。
float f = 5e-1;
printf("%x", *(int*)&f);
这是未定义的行为:标准不保证指向int
和float
指针具有相同的对齐方式,因此(int*)&f
cast是无效的( Q&A )。
在您的情况下,强制转换产生的值与以下的IEEE-754表示形式0.5(5e-1)一致:
bin: 0011 1111 0000 0000 0000 0000 0000 0000
+--- ---- -=== ==== ==== ==== ==== ====
hex: 3 f 0 0 0 0 0 0
其中+
是符号位, -
是指数位, =
是尾数位。
但是,绝对不能保证在其他系统上运行该程序时,该程序将产生相同的结果,甚至无法保证该程序将运行至完整状态。
您可能更喜欢
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);
由于(int*)&f
,代码的行为未定义。 C类型转换无效,因为类型无关。
如果要检查与f
相关联的内存,则C和C ++都允许您将其强制转换为const unsigned char*
,并使用指针算法跟踪内存,直到sizeof(f)
为止。
因为您是C / C++
新手,所以-您可能对undefined behaviors
没有任何想法。 简而言之,在某些方面, C / C++
语言没有define
应该确切发生的事情。 为什么? 背后有很多原因,例如性能。 在那些情况下,行为的结果或效果完全取决于实现(编译器-更具体地说(例如gcc,vc ++))。
C ++程序员应该知道的所有常见未定义行为是在已接受答案的第7条中列出的。
其他人已经解决了未定义的行为,所以我只解决这一部分:
我很难理解为什么此代码会导致3f000000
该代码尝试打印浮点值0.5(或5e-1)的二进制表示形式。
( 尽管这样做是非法的-请参阅其他答案以了解正确的方法 -请参阅此答案https://stackoverflow.com/a/45036945/4386427 )
值3f000000的解释是您的系统似乎使用IEEE 754单精度二进制浮点格式(请参阅https://en.wikipedia.org/wiki/Single-precision_floating-point_format )。
格式使用
所以你的情况
通常,该值计算为:
值=(-1)^符号*(1 +分数)* 2 ^(指数-127)
由于符号和小数均为0,因此很容易计算出该值:
值= 1 * 1 * 2 ^(126-127)= 2 ^ -1 = 0.5
因此,对于IEEE 754单精度二进制浮点,将使用二进制模式3f000000存储值为0.5的浮点数
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.