私は尋ねた:
コードが整数で動作しているのに、なぜタイトルの「浮動小数点数」について尋ねているのですか? 関数を a で呼び出して、float
多かれ少なかれビットの配列として扱おうとしていますか? もしそうなら、あなたは何にも隠れていません!スコープ内のプロトタイプで関数を呼び出すと、C コンパイラは を に変換float
しunsigned int
ます。スコープ内のプロトタイプでそれを呼び出さない場合、C コンパイラは関数を呼び出す前に を に変換float
します。double
そして、応答は次のとおりでした。
これは、32 ビットの IEEE 754 単精度数です。したがって、最上位ビット (符号ビット) を反転しているだけです。
32 ビット (符号なし整数) 量の最上位ビットを反転するには、単純に次のように記述できます。
x ^= 0x80000000;
ただし、私が示したようfloat
に、コンパイラに嘘をついていない限り、32 ビットが渡されないだけです。次のものがあれば、「動作させる」ことができます(一部のマシンでは、場合によっては):
偽のコード
ファイルA.c
extern float negate_number(float x);
...
float f1 = 3.14159;
float f2 = negate_number(f1);
...
ファイルB.c
unsigned negate_number(unsigned x)
{
return x ^ 0x80000000;
}
ただし、コンパイラに火をつけて遊んでいます。コンパイラは嘘をつくことを嫌い、しばしば自分自身を取り戻す方法を見つけます。 こんなことしないで!
主にコーシャコード
最小限の問題で(「問題なし」ではない)必要な効果を多かれ少なかれ達成するには、おそらく次のものが必要です。
ファイルB.c
float negate_number(float f)
{
union { unsigned x; float y; } u;
u.y = f;
u.x ^= 0x80000000;
return u.y;
}
u.x
厳密には、に割り当てた後の読み取りと書き込みu.y
は未定義の動作ですが、通常は必要なことが行われます。u.y
操作後に戻る場合も同様u.x
です。
float
これはすべて、とのビット レイアウトがunsigned
の符号ビットfloat
が の最上位ビットになることを前提としていますunsigned
。