使用c - printf将ieee 754 float转换为hex

Mic*_*ael 17 c floating-point ieee-754

理想情况下,以下代码将采用IEEE 754表示形式的浮点数并将其转换为十六进制

void convert() //gets the float input from user and turns it into hexadecimal
{
    float f;
    printf("Enter float: ");
    scanf("%f", &f);
    printf("hex is %x", f);
}
Run Code Online (Sandbox Code Playgroud)

我不太确定会出现什么问题.它将数字转换为十六进制数,但却是一个非常错误的数字.

123.1443 gives 40000000
43.3     gives 60000000
8        gives 0
Run Code Online (Sandbox Code Playgroud)

所以它正在做某事,我只是不太确定是什么.

帮助将不胜感激

Jam*_*lis 26

当你将一个float参数作为一个参数传递给一个变量函数(比如printf())时,它被提升为a double,它是a的两倍float(至少在大多数平台上).

要解决这个问题的一个方法是投了float一个unsigned int路过的时候它作为参数printf():

printf("hex is %x", *(unsigned int*)&f);
Run Code Online (Sandbox Code Playgroud)

这也更正确,因为printf()使用格式说明符来确定每个参数的大小.

从技术上讲,此解决方案违反了严格的别名规则.您可以通过将其中的字节复制float到一个unsigned int然后将其传递给printf():

unsigned int ui;
memcpy(&ui, &f, sizeof (ui));

printf("hex is %x", ui);
Run Code Online (Sandbox Code Playgroud)

这两种解决方案都基于这样的假设sizeof(int) == sizeof(float),即许多32位系统就是这种情况,但不一定如此.

  • @Nyan:因为它不会将位重新解释为无符号值,所以会将float转换为无符号值(因此,24.12将变为24,这不是期望的结果). (4认同)
  • 这次自动促销让我花了很多时间.这么多的挫折:( (2认同)

dra*_*ard 12

支持时,使用%a将浮点数转换为标准十六进制格式.这是我能找到的唯一列出%a选项的文档.

否则,您必须将浮点值的位拉入已知大小的整数类型.例如,如果您知道float和int都是32位,则可以快速执行:

printf( "%08X" , *(unsigned int*)&aFloat );
Run Code Online (Sandbox Code Playgroud)

如果您希望减少对大小的依赖,可以使用联合:

union {
  float f;
//char c[16]; // make this large enough for any floating point value
  char c[sizeof(float)]; // Edit: changed to this
} u;

u.f = aFloat;
for ( i = 0 ; i < sizeof(float) ; ++i ) printf( "%02X" , u.c[i] & 0x00FF );
Run Code Online (Sandbox Code Playgroud)

循环的顺序取决于体系结构字节顺序.这个例子是大端.

无论哪种方式,浮点格式都可能无法移植到其他架构.%a选项旨在用于.