[解決済み] なぜこの2つのコードは異なる出力をするのでしょうか?// bits.c float_i2f
2022-02-02 23:54:44
質問
/*
* float_i2f - Return bit-level equivalent of expression (float) x
* Result is returned as unsigned int, but
* it is to be interpreted as the bit-level representation of a
* single-precision floating point values.
* Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
* Max ops: 30
* Rating: 4
*/
unsigned float_i2f(int x) {
int sign = x & (1 << 31);
int minus = 1 << 31;
int exp = 31;
int bias = 127;
int frac;
if (!x)
return 0;
if (x == minus)
return minus | ((exp + bias) << 23);
if (sign)
x = ~x + 1;
while (!(x & minus))
{
x <<= 1;
exp -= 1;
}
frac = (((~minus) & x) >> 8);
if (x & 0x80 && ((frac & 1) ||((x & 0x7f) > 0)))
frac++;
return sign + ((exp + bias) << 23) + frac;
}
このコードをdriver.plでチェックすると、答えの正しさがチェックされる。 しかし、私は奇妙なことを発見しました。
最後のreturn文が
return sign | ((exp + bias) << 23) | frac;
に変更すると、うまくいかないと表示されます。
return sign + ((exp + bias) << 23) + frac;
が正しくなります。
2つのコードの違いは何ですか?なぜ最初のものは動作しないのでしょうか? 私を助けてください :(
解決方法は?
この問題は、数字が大きくなると発生します。例えば、2 25 - 1 = 33554431で、その2の補数2進表現は次のようになります。
00000001 11111111 11111111 11111111 // or --> 0 00000011 11111111111111111111111
指数を求めた後、このコードでは
frac
として
frac = (((~minus) & x) >> 8); // --> 0 00000000 11111111111111111111111
しかし、これを丸めなければならないので、次のように実行されます。
if (x & 0x80 && ((frac & 1) ||((x & 0x7f) > 0)))
frac++; // --> 0 00000001 00000000000000000000000
基本的にキャリーがあるので、999を1x10と表現する場合のように指数を大きくする必要があります。
3
ではなく、9.99x10
2
. の違いがわかるようになりました。
|
または
+
:
sign + ((exp + bias) << 23) + frac; // --> 0 10011000 00000000000000000000000
sign | ((exp + bias) << 23) | frac; // --> 0 10010111 00000000000000000000000
関連
-
[解決済み】getline()が何らかの入力の後に使用されると動作しない 【重複あり
-
[解決済み】非静的メンバ関数への参照を呼び出す必要がある
-
[解決済み】変数 '' を抽象型 '' と宣言できない。
-
[解決済み】「corrupted size vs. prev_size」glibc エラーを理解する。
-
[解決済み】「std::operator」で「operator<<」にマッチするものがない。
-
[解決済み】C++の余分な資格エラー
-
[解決済み] 解決済み] `pthread_create' への未定義の参照 [重複] [重複
-
[解決済み】システムが指定されたファイルを見つけられませんでした。
-
[解決済み] 要素ごとの加算は、結合ループよりも分離ループの方がはるかに高速なのはなぜですか?
-
[解決済み] C++のヘッダーファイルで#ifndefと#defineが使われているのはなぜですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】コンストラクターでのエラー:識別子を期待されますか?
-
[解決済み】C++ クラスヘッダが含まれているときに「不明な型」があるのはなぜですか?重複
-
[解決済み】Visual Studio 2015で「非標準の構文; '&'を使用してメンバーへのポインターを作成します」エラー
-
[解決済み】Visual Studio 2015で「非標準の構文。'&'を使用してメンバーへのポインターを作成します」エラー
-
[解決済み】cc1plus:エラー:g++で認識されないコマンドラインオプション"-std=c++11"
-
[解決済み】CMakeエラー at CMakeLists.txt:30 (project)。CMAKE_C_COMPILER が見つかりませんでした。
-
[解決済み】VC++の致命的なエラーLNK1168:書き込みのためにfilename.exeを開くことができません。
-
[解決済み】Visual Studioのデバッガーエラー。プログラムを開始できません 指定されたファイルが見つかりません
-
[解決済み] 配列のベクトルを扱う正しい方法
-
[解決済み】'std::cout'への未定義の参照