我正在尝试使用 union 来获取浮点值的位表示,目前我的代码如下:
union ufloat {
float f;
unsigned u;
};
int main( ) {
union ufloat u1;
u1.f = 3.14159f;
printf("u1.u : %f\n", u1.u);
但是我尝试打印的任何内容都打印为 0.0000000,而不是位(例如 0001 0110 或类似的东西),我的代码有什么问题吗?
请注意,我更愿意使用 union 来实现这一点。
最佳答案
有很多方法可以实现这一点。明白你真正想做的只是输出内存中组成 float
的位。 .在几乎所有 x86 类型实现中,它都以 IEEE-754 单精度浮点格式 存储。在 x86 上是 32 位数据。这就是允许在转换 float
时“窥视”位的原因。至 unsigned
(两者都是 32 位的,并且为 unsigned
类型定义了位操作)对于 x86 以外的实现,甚至在 x86 本身上,unsigned
是更好的选择将是 uint32_t
的确切长度类型由 stdint.h
提供.这样大小就没有歧义了。
现在,转换本身在技术上不是问题,它是值的访问,尽管取消引用您运行的不同类型(又名类型双关)违反了strict-aliasing 规则(C11 标准的第 6.5 (7) 节)。 union
的 float
和 uint32_t
类型为您提供了一种查看 float
的有效方式通过 unsigned
位类型窗口。 (无论哪种方式,您都在查看相同的位,这只是您如何访问它们并告诉编译器应该如何解释它们)
也就是说,您可以从此处的所有答案中收集有用的信息。您可以编写函数来访问和存储 float
的位表示形式字符串中的值供以后使用,或将位值输出到屏幕。作为大约一年前玩浮点值的练习,我写了一个小函数以注释的方式输出位,这样可以轻松识别符号、归一化指数和尾数。您可以调整它或其他答案例程来满足您的需求。简短的例子是:
#include <stdio.h>
#include <stdint.h>
#include <limits.h> /* for CHAR_BIT */
/** formatted output of ieee-754 representation of float */
void show_ieee754 (float f)
{
union {
float f;
uint32_t u;
} fu = { .f = f };
int i = sizeof f * CHAR_BIT;
printf (" ");
while (i--)
printf ("%d ", (fu.u >> i) & 0x1);
putchar ('\n');
printf (" |- - - - - - - - - - - - - - - - - - - - - - "
"- - - - - - - - - -|\n");
printf (" |s| exp | mantissa"
" |\n\n");
}
int main (void) {
float f = 3.14159f;
printf ("\nIEEE-754 Single-Precision representation of: %f\n\n", f);
show_ieee754 (f);
return 0;
}
示例使用/输出
$ ./bin/floatbits
IEEE-754 Single-Precision representation of: 3.141590
0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 0 0 1 1 1 1 1 1 0 1 0 0 0 0
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -|
|s| exp | mantissa |
检查一下,如果您有任何问题,请告诉我。
关于c - 在 C 中获取 float 的位表示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44609743/