如何在 C 中以十六进制字节格式打印浮点数?

2023-12-15

我想查看 IEEE754 格式表示形式的浮点值 3.14159265。于是写了这段测试代码。

#include <stdio.h>

main()
{
int i;
float a = 3.141592654;

printf("a = %f\n", a);

// print test 1
printf("test 1 : a = %x\n", a);
printf("test 1 2nd time : a = %x\n", a);

// print test 2
char *pt = (char *)&a;
printf("test 2 :\n");
for(i=0;i<4;i++){
    printf("%x ", (char)(*pt++));
}
printf("\n");
}

当我运行它几次时,它显示如下:

ckim@stph45:~/test5] test
a = 3.141593
test 1 : a = e0cd2000
test 1 2nd time : a = e0cd2000
test 2 :
ffffffdb f 49 40 
ckim@stph45:~/test5] test
a = 3.141593
test 1 : a = 520db000
test 1 2nd time : a = 520db000
test 2 :
ffffffdb f 49 40 
ckim@stph45:~/test5] test
a = 3.141593
test 1 : a = 3b373000
test 1 2nd time : a = 3b373000
test 2 :
ffffffdb f 49 40 
ckim@stph45:~/test5] test
a = 3.141593
test 1 : a = 18a6d000
test 1 2nd time : a = 18a6d000
test 2 :
ffffffdb f 49 40 

第一个问题是:当使用 printf 和 %x 时,我期望看到 40490fdb,即 IEEE754 格式的 3.14159265。但正如你所看到的,每次我运行它时,值都会发生变化。这里有什么问题吗?也许我错过了一些非常基本的东西。

另一个问题是,当我使用字符指针并打印上面测试 2 中的十六进制值时,如何打印“db”而不是“fffffdb”? (该值显示为符号扩展)。我想我以前做过这些事情,但现在想不起来了。 (我的机器是小端字节序,所以首先显示 LSB。)


您缺少的是如何获得有效的look构成 IEEE-754 单精度浮点数的位与其等效unsigned int记忆中的表征。为了做到这一点,同时避免违反严格别名规则(类型双关指针),您可以使用union之间float and unsigned(或更好uint32_t对于精确宽度类型),例如

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

int main (void) {

    float pi = (float)M_PI;
    union {
        float f;
        uint32_t u;
    } f2u = { .f = pi };

    printf ("pi : %f\n   : 0x%" PRIx32 "\n", pi, f2u.u);

    return 0;
}

Using unsigned代替uint32_t并理解它可能不是所有硬件上的 32 位,标准格式字符串就足够了,例如printf ("pi : %f\n : 0x%0x\n", pi, f2u.u);。 (您可以删除包含stdint.h and inttypes.h在这种情况下)

使用/输出示例

当解释为无符号类型时,这将允许您获得构成浮点数的位的十六进制表示形式:

$ ./bin/float_hex
pi : 3.141593
   : 0x40490fdb
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 C 中以十六进制字节格式打印浮点数? 的相关文章

随机推荐