2

4つの要素のchar配列をfloat数値として出力しようとしています。コンパイラ(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、float変数が格納できるよりもはるかに大きい数値。出力は、科学的記数法で、である必要があります4.1977085E-8。では、何が問題なのですか?

4

2 に答える 2

6

z.s={'3','4','j','k'};ある配列を別の配列に割り当てます。Cはそれを許可していませんが、2番目とmemcpy1番目を宣言することはできます。

単精度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

于 2012-08-18T16:50:18.930 に答える
1

実際に表示されるのは{'k''j''4''3'}です。

于 2013-01-30T18:57:47.147 に答える