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

如何在C中以十六进制字节格式打印浮点?,c,floating-point,printf,C,Floating Point,Printf,我想在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 = (

我想在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");
}
第一个问题是:当将printf与%x一起使用时,我希望看到40490fdb,它是IEEE754格式的3.14159265。但是,正如您所看到的,每次我运行它时,该值都会发生变化。这里怎么了?也许我错过了一些非常基本的东西


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

您缺少的是如何有效地查看组成IEEE-754单精度浮点数的位,将其作为内存中的等效
无符号int
表示。要做到这一点,同时避免违反严格的别名规则(键入双关指针),您可以在
浮点
无符号
之间使用
并集
(对于精确的宽度类型,最好使用
uint32\u t


我想我一直在寻找的答案是这样的

float a = 3.141592654;
printf("test 1 2nd time : a = %x\n", *(unsigned int*)&a);
然后我得到

test 1 2nd time : a = 40490fdb

要明确的是,OP的代码并没有因为“严格的别名规则”而失败

代码失败,因为“%x”需要一个无符号的,并且代码传递了一个浮点数。这是未定义的行为(UB)。由于FP值有时以与整数不同的方式传递,这并不奇怪

float a = 3.141592654;   
printf("test 1 : a = %x\n", a); // bad code

OP后来的代码几乎是正确的。只需在说明符中使用对象的大小和
hh
,即可只打印值,而不打印带符号的扩展名

打印顺序取决于
浮点数的尾数。由于
float
的endian和
int
的endian可能不同,因此使用并集仍然不是正确的endian-尽管这并不常见

char *pt = (char *)&a;
//for(i=0;i<4;i++){
for(i=0;i<sizeof a;i++){
  //printf("%x ", (char)(*pt++));
  printf("%02hhx ", *pt++);
}
char*pt=(char*)&a;

//对于(i=0;i)您在这里所做的是未定义的行为。在“打印测试2”中编码,使用
unsigned char
,从3循环到0,然后用
%02x
打印,你就会得到你想要的。@user2357112当我使用%a时,我得到
a=0x1.921fb6p+1
。我想看到十六进制的值。@user3386109好的,我知道它是小尾数,所以从3向下打印到0将显示它是正确的。更改为unsigned char后,我得到了et
40 49 0f db
。一个问题解决了!谢谢。很好,在联合体中添加一个“char pt[4];”也解决了char问题。非常正确-只要你遵守规则,你就可以以任何方式组成32位。
char[4]
唯一的问题是,然后你被留给
unsigned
(或
uint32\u t
)稍后(键盘rant被删除)
:)
谢谢,使用union是一种方法。我用
*(unsigned int*)&a给出了我的答案,这就是我想要的简单方法。@Chan Kim:你的“简单方法”坏了。@chux
float a=3.141592654*(unsigned int*)和a
在注释(上面第6条)第号
*(unsigned int*)和a
-这是一种严格的别名冲突,不保证有效。该行为未定义。如果你想重新解释记忆,请使用@David C.Rankin建议的联合。
test 1 2nd time : a = 40490fdb
float a = 3.141592654;   
printf("test 1 : a = %x\n", a); // bad code
char *pt = (char *)&a;
//for(i=0;i<4;i++){
for(i=0;i<sizeof a;i++){
  //printf("%x ", (char)(*pt++));
  printf("%02hhx ", *pt++);
}