3

以下を考えると...

void test(){
  float a = 0.7f;
  LOGD("Width %.1f",0.7f);
  LOGD("Width %.1f",a);
  fark(a);
}

void fark(float test){
  LOGD("Width %.1f",test);
}

これは出力します....

05-18 22:35:25.215: D/ネイティブ (8241): 幅 0.7

05-18 22:35:25.215: D/ネイティブ (8241): 幅 0.7

05-18 22:35:25.215: D/ネイティブ (8241): 幅 36893488147419103232.0

私は最後のものについて何が欠けていますか?

4

1 に答える 1

12

fark使用する前に宣言する必要があります。セクション 6.5.2.2、パラグラフ 6 で指定されているとおり:

呼び出された関数を示す式がプロトタイプを含まない型を持つ場合、各引数に対して整数昇格が実行され、型を持つ引数floatは に昇格されdoubleます。これらはデフォルト引数のプロモーションと呼ばれます。

(私が追加した太字の強調)。

暗黙的に想定された型と互換性のない型で定義することfarkは制約違反であり、呼び出しと定義が同じ変換単位にある場合、コンパイラは診断メッセージを発行する必要があることに注意してください。gcc はその場合にのみ警告しますが、clang はコード [ error: conflicting types for 'fark'] を拒否します。呼び出しと定義が異なる翻訳単位にある場合、コンパイラはもちろん間違いを診断できませんが、互換性のない型の式を介して関数を呼び出すと、いずれにしても未定義の動作が呼び出されます。

0.7fが変換されると( IEEE754 32 ビット表現とIEEE754 64ビット表現を使用するdoubleと想定しています)、次の値が得られます。floatdouble

0.699999988079071

そのビットパターン (16 進表記) は

0x3FE6666660000000

(バイアスされた指数は 1022 で、有効指数 に対応し、仮数-1は です1.6666660000000)。

これは、スタック上またはレジスタ内で に渡されfarkます。

farkその表現から 32 ビットを読み取る場合float(その定義に従って a が予期されるため)、 が渡される方法に応じてdouble、上位 32 ビットまたは下位 32 ビットが読み取られる場合があります。

この場合、下位 32 ビットを読み取ったためfloat、ビットパターンの値が得られました。

0x60000000

これは、偏りのない指数と仮数0xC0 = 192に対応する の偏りのある指数を持ちます。言い換えれば、それはの表現です192 - 127 = 651.000000float

2^65 = 36893488147419103232

これは印刷された値です。

于 2013-05-18T23:10:13.503 に答える