使用%d说明符浮点

时间:2018-01-03 15:18:13

标签: c

void main()
{
  float a=2;
  printf("%d",a);
}

在我的机器中,float是4个字节,int是2个字节,字节以little-endian格式存储。

a是0x 00 00 00 02

现在我的机器是小端,字节应该存储为0x 02 00 00 00

现在当我使用%d指定符时,应该获取前2个字节,输出应该是512,但我没有得到那个输出。

有人可以告诉我为什么会这样吗?

2 个答案:

答案 0 :(得分:2)

使用错误的格式说明符printf调用undefined behavior

在这种特殊情况下,可能发生的事情是浮点类型不会像整数类型一样被推入堆栈。但是你不能依赖这种行为,因为标准没有规定会发生什么。

如果要打印float中的字节,请指向unsigned char并循环显示字节:

float a=2;
unsigned char *c = (unsigned char *)&a;
int i;
for (i=0; i<sizeof(float); i++) {
    printf("%02x ", c[i]);
}
printf("\n");

此外,假设您的计算机使用IEEE754格式表示浮点数,则2的表示形式不是0x00000002,而是0x40000000

答案 1 :(得分:1)

您好像假设在printf("%d", a)中,float的{​​{1}}值将被放置在传递a值的同一位置因此,int参数会int读取printf的字节,就好像它们是float一样。

这不是许多C实现中发生的事情。 C标准并未说明所有参数都以相同的方式或相同的方式传递,无论其类型如何。当您将不匹配的参数传递给int时,它不会定义行为。在许多C实现中,前几个浮点参数在处理器的浮点寄存器中传递,这些寄存器与通用整数寄存器分开。

如果要检查对象的字节,支持的方法包括:

  • 将指向对象的指针转换为指向printf的指针,然后通过指向unsigned char的指针检查字节。

  • 使用unsigned char将字节复制到另一个对象,例如memcpy。 (目标对象应与源对象的大小相同,因此这取决于实现。)

  • 声明一个包含两种类型对象的联合,即您要检查的类型和另一种类型,如int x; memcpy(&x, &a, sizeof a);int数组。将值写入联合的一个成员并从另一个成员中读取它。例如,unsigned char。同样,两个对象的大小应该匹配。