C打印char数组为float

时间:2012-08-18 16:43:09

标签: c floating-point unions

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

#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;
}

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

2 个答案:

答案 0 :(得分: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

所以:

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)

所以这个值大概是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)

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

摘要:机器之间的字节顺序不同。您希望以相反的方式使用您的字节 - 尝试kj43

答案 1 :(得分:1)

你实际看到的是{'k''j''4''3'}