c - 在 C 中获取 float 的位表示

标签 c floating-point bit-manipulation

我正在尝试使用 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) 节)。 unionfloatuint32_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/

相关文章:

c - 为什么不能直接删除第一个节点(头节点)?

c++ - 什么样的 GCC 优化可能会根据是否打印来更改 double?

ios - 有什么简单的方法可以在 objective-c 中用一位数舍入 float 吗?

c - 在 C 中使用未声明的标识符 'a'

C:字符数组索引并使用 strcmp

C不能打印一个字符串两次

C 未定义行为 - 单链表

c - C语言中通过整数转换进行 float 比较

go - Go中无符号整数的二进制表示

如果位移太多,Javascript 数字将重置为 0