C打印char数组为float

Cri*_*sti 2 c floating-point unions

我正在尝试打印一个包含4个元素的char数组作为浮点数.编译器(gcc)不允许我z.s={'3','4','j','k'};在main()函数中写入,为什么?

#include <stdio.h>

union n{
    char s[4];
    float x;
};
typedef union n N;

int main(void)
{
    N z;
    z.s[0]='3';
    z.s[1]='4';
    z.s[2]='j';
    z.s[3]='k';
    printf("f=%f\n",z.x);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

上面程序的输出是:f=283135145630880207619489792.000000,一个比浮点变量大得多的数字可以存储; 输出应该是科学记数法4.1977085E-8.那有什么不对?

Tom*_*mmy 6

z.s={'3','4','j','k'};将一个数组分配给另一个.C不允许这样做,尽管你可以声明第二个和memcpy第一个.

单精度IEEE浮点可以存储的最大有限值是3.4028234×10 ^ 38,所以283135145630880207619489792.000000,大约是2.8313514×10 ^ 26,绝对是在范围内.

假设你的字符是正确的,那么下意识的猜测就是你的字节序错了.

编辑:如果从左到右拍摄34jk,就像在大端机器上一样:

0x33 0x34 0x6a 0x6b
= 0011 0011, 0011 0100, 0110 1010, 0110 1011
Run Code Online (Sandbox Code Playgroud)

所以:

sign = 0
exponent = 011 0011 0 = 102 (dec), or -25 allowing for offset encoding
mantissa = [1] 011 0100 0110 1010 0110 1011 = 11823723 / (2^23)
Run Code Online (Sandbox Code Playgroud)

所以这个值大概是4.2×10 ^ -8,这就是你想要的.

在小端:

0x6b 0x6a 0x34 0x33 
= 0110 1011, 0110 1010, 0011 0100, 0011 0011

sign = 0
exponent = 110 1011 0 = 214 (dec) => 87
mantissa = [1]110 1010 0011 0100 0011 0011 = 15348787 / (2^23)
Run Code Online (Sandbox Code Playgroud)

所以这个值大概是2.8*10 ^ 26,这是你的程序输出的.这是一个安全的结论,你在一个小端机器上.

总结然后:机器之间的字节顺序是不同的.你想反过来使用你的字节 - 试试kj43.