【问题标题】:How to display the encoding of a floating-point value如何显示浮点值的编码
【发布时间】:2013-07-15 21:46:25
【问题描述】:

我们如何在 C 中打印浮点值的编码? 我知道我可以使用%A,但这不是我想要的格式。

例如,如果我的值为1.3416407,我想打印“0x3FABBAE2”,我不打印“0X1.5775C4P+0”。

【问题讨论】:

  • 我很高兴您希望 0x 作为十六进制数字的前缀和大写 A-F。请注意,该标准并不容易。您必须明确编码格式(例如"0x%.8X")。如果使用%X,则前缀为 0X,数字为 A-F;如果你使用%x,你会得到 0x 作为前缀,但 a-f 是数字。

标签: c math floating-point formatting


【解决方案1】:

你可以使用联合,例如

#include <stdio.h>
#include <stdint.h>

union {
    float f;
    uint32_t i;
} u;

u.f = 1.3416407f;
printf("%#X\n", u.i);

【讨论】:

  • 谢谢!我在任何地方都找不到这个!
  • 没关系,但我认为浮点中的最大位数是6。 +1 使用 32 位整数而不是 int
  • @Taylor Flores, 6 可能来自 FLT_DIG "十进制位数,q,这样任何具有 q 十进制数字的浮点数都可以四舍五入为具有 p 基数 b 位的浮点数并再次返回而不更改 q 十进制数字,”。所以如果你是往返,6 是可以的。如果您想要“最大位数”,则需要更精确的定义。你需要做一个“%.7e”来 printf() 所有的浮动都清楚。
【解决方案2】:

@Paul R 提出的联合想法很好,但会随着改进而受益

union {
    float f;
    uint32_t i;
} u;

u.f = 1.3416407f;
printf("0x%08" PRIX32 "\n", u.i);

这可确保打印 8 个十六进制字符,并根据需要填充零。如果它与 sizeof(int) 不同,它也匹配 sizeof(u.i)。

虽然它确实应该受到不常见的 sizeof(float) != sizeof(uint32_t);

【讨论】:

    【解决方案3】:

    要打印任意事物的十六进制表示,请使用

    union {
        arbitrary object;
        unsigned char bytes[sizeof (arbitrary)];
    } u;
    

    union {
        float object;
        unsigned char bytes[sizeof (float)];
    } u;
    
    u.object = 1.3416407f;
    printf("0x");
    for (size_t i = 0; i < sizeof(u.bytes); i++) {
        printf("%02hhx", u.bytes[i]);
    }
    printf("\n");
    

    或者为小端反转字节:

    printf("0x");
    for (size_t i = sizeof(u.bytes) - 1; i < sizeof(u.bytes); i--) {
        printf("%02hhx", u.bytes[i]);
    }
    printf("\n");
    

    上面的代码假设CHAR_BIT == 8

    【讨论】:

    • @chux 好点:D 我盯着输出,因为它看起来不错,我没有注意到我没有指定宽度。
    • 对于迂腐的:像printf("%0*hhx", (CHAR_BIT+3)/4, u.bytes[i]); 这样的答案仍然足够好,因为CHAR_BIT == 8非常常见的。
    【解决方案4】:

    你可以逐个字节遍历类型字节:

    float f = 1.3416407;
    unsigned char *fp = (void *)&f;
    size_t i;
    printf("0x");
    for (i = 0; i < sizeof(float); ++i) {
        printf("%02X", fp[i]);
    }
    puts("");
    

    您可能需要根据所需的字节序以相反的顺序打印八位字节。

    【讨论】:

    • 不是我的反对票,但i[(uint8_t *)&amp;fl] 符号可能是一个因素。
    • 嗯,由于anti-aliasing,这似乎失败了。
    • 是因为 C11 §6.5 7 吗?
    • @chux:是的,最后一个要点是char 类型的豁免。
    猜你喜欢
    • 2015-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多