将整数转换为浮点数再转换为十六进制

6
使用scanf,每输入一个数字,我想让程序打印出两行结果,例如:
byte order: little-endian

> 2
     2 0x00000002
  2.00 0x40000000

> -2
    -2 0xFFFFFFFE
 -2.00 0xC0000000

我可以将它以十六进制打印出来,但我还需要一个浮点数,当然我不能用scanf读取一个浮点数,因为我也需要以int的形式扫描。

如果我将其转换成浮点数后再尝试printf,那么输出会变成零。如果我以浮点数的形式进行扫描,则可以得到正确的输出。我已经尝试将int转换为float,但结果仍然是零。

以下是我的输出结果:

Int - float - hex

byte order: little-endian

>2

         2  0x000002
      2.00  00000000

看起来我成功地将其转换为浮点数了,但为什么不能以十六进制形式打印出来呢?如果我将其作为浮点数扫描,则会像第一个示例一样得到正确的十六进制表示。这应该是一个简单的问题。我确实需要将其作为十进制数扫描。请记住,我在Cygwin中运行此程序。

以下是我目前所拥有的内容:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{


int HexNumber;
    float convert;
printf("Int - float - hex\n");



int a = 0x12345678;
unsigned char *c = (unsigned char*)(&a);
if (*c == 0x78)
{
    printf("\nbyte order: little-endian\n");
}
else
{
    printf("\nbyte order: big-endian\n");
}

printf("\n>");
scanf("%d", &HexNumber);
printf("\n%10d  ",HexNumber);
printf("%#08x",HexNumber);





convert =  (float)HexNumber; // converts but prints a zero

printf("\n%10.2f  ", convert); 
printf("%#08x", convert); // prints zeros


return 0;
}

你能展示一些代码吗? - Wayne Conrad
当我输入1时,它不会为我打印零。你想要实现什么?你的输入数字是多少? - Mehrdad Afshari
我的输入数字是2,就像我想要的输入一样。 - Steller
3个回答

8
尝试这个:
int i = 2;
float f = (float)i;
printf("%#08X", *( (int*) &f ));

[编辑]

@Corey:

让我们从内向外解析它:

&  f = address of f = say address 0x5ca1ab1e
(int*)  &f = interpret the address 0x5ca1ab1e as integer pointer
*  ((int*)&f) = get the integer at address 0x5ca1ab1e

以下内容更为简洁,但是很难记住C语言的运算符结合性和优先级(我更喜欢添加一些括号和空格提供的额外清晰度):
printf("%#08X", *(int*)&f);

看起来我编辑了我的答案,同时包含了相同的内容。 - Trent
1
如果 (sizeof(int) != sizeof(float)),那么你会遇到问题。 - plinth
你能解释一下*((int *)&f))的作用吗?我理解指针和地址。 - Steller
如果您理解指针和地址,只需逐步跟踪它,您就应该看到它在做什么。 - Stephen Canon

4
printf("%#08x", convert); // prints zeros

这行代码行不通,因为你告诉printf你正在传递一个int(通过使用%x),但实际上你正在传递一个float

你的意图是什么?想以十六进制显示浮点数的二进制表示吗?如果是这样,你可以尝试像这样:

printf("%lx\n", *(unsigned long *)(&convert));

这行代码的作用是获取convert的地址(&convert),它是一个指向浮点数的指针,并将其转换为指向无符号长整型的指针(注意:这里转换的类型可能因系统中float和long的大小而异)。最后的*是将指向无符号长整型的指针解引用为无符号长整型,并将其传递给printf函数。

感谢您对您所做的事情进行解释。非常有帮助。 - Steller
我很好奇如何使其格式化为0xFFFFFFFE,而不是0xffffffe。如果我使用大写字母X,它会变成0XFFFFFFFE,我需要小写字母x和其他字母大写。 - Steller
1
@Corey,使用“0x%08X”代替“%#08X”。 - Trent
Trent,你非常有帮助。我本来会选择你的解决方案的。但是,你发帖比较晚。除非你真的想要它。不过我还是给了你积分。 - Steller

1

给定一个整数x,将其转换为浮点数,然后以十六进制打印出该浮点数的字节可以像这样完成:

show_as_float(int x) { 
   float xx = x;

   //Edit: note that this really prints the value as a double.
   printf("%f\t", xx);

   unsigned char *ptr = (unsigned char *)&xx;

   for (i=0; i<sizeof(float); i++)
       printf("%2.2x", ptr[i]);
}

标准(C++ 和 C99)为 unsigned char 提供了“特殊豁免”,因此可以安全地使用它们来查看任何对象的字节。尽管 C89/90 没有保证这一点,但它仍然相当可移植。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接