[解決済み] C#でfloat変数が16777216でインクリメントを停止するのはなぜですか?
2022-01-31 01:36:30
質問
float a = 0;
while (true)
{
a++;
if (a > 16777216)
break; // Will never break... a stops at 16777216
}
なぜこのコードでは、floatの値が16777216でインクリメントを停止するのか、誰かこれを説明してくれませんか?
編集してください。
あるいは、もっとシンプルに。
float a = 16777217; // a becomes 16777216
解決方法は?
IEEE-754浮動小数点数(32ビット)の頭文字をとって短くまとめたものです。
- 1ビット符号(0は正の数、1は負の数)
- 8ビットの指数(-127のバイアス付き、ここでは重要ではない)
- 23ビットの仮数。
-
指数値0と255の例外を除いて、次のように計算することができます。
(sign ? -1 : +1) * 2^exponent * (1.0 + mantissa)
-
仮数ビットは
バイナリ
桁
後
は、小数点以下の区切り文字です。
1001 0000 0000 0000 0000 000 = 2^-1 + 2^-4 = .5 + .0625 = .5625
で、小数点以下の値は格納されず、暗黙のうちに 1 とみなされます(指数が 255 の場合は 0 とみなされますが、ここでは重要ではありません)。したがって、たとえば指数が 30 の場合、この仮数の例では、次のような値を表します。1.5625
-
仮数ビットは
バイナリ
桁
後
は、小数点以下の区切り文字です。
さて、例の件です。
16777216はちょうど2 24 というように、32ビットフロートで表現される。
- 符号 = 0 (正の数)
-
指数=24(24+127=151=として格納されます。
10010111
) - 仮数 = .0
-
32ビット浮動小数点表現として。
0 10010111 00000000000000000000000
-
したがって 値 =
(+1) * 2^24 * (1.0 + .0) = 2^24 = 16777216
次に、16777217という数字、つまりちょうど2について見てみましょう。 24 +1:
- 符号と指数が同じ
-
仮数は正確に2でなければならない
-24
そうすると
(+1) * 2^24 * (1.0 + 2^-24) = 2^24 + 1 = 16777217
- そして、問題はここからです。 仮数は値2であってはならない -24 というのは、23ビットしかないので、16777217という数字は32ビット浮動小数点数の精度で表すことができないのです!
関連
-
[解決済み】ファイルへの読み書きの際に共有違反のIOExceptionが発生する C#
-
[解決済み] C#がforeachで変数を再利用するのは理由があるのか?
-
[解決済み] 0.1fを0にすると、なぜ10倍もパフォーマンスが落ちるのですか?
-
[解決済み] Try-catchは私のコードをスピードアップさせるか?
-
[解決済み] なぜList<T>を継承しないのですか?
-
[解決済み] EqualsメソッドがオーバーライドされたときにGetHashCodeをオーバーライドすることが重要な理由は何ですか?
-
[解決済み] 通貨を表すのにDoubleやFloatを使ってはいけないのですか?
-
[解決済み] Entity Framework 5 レコードを更新する
-
[解決済み] Math.round(0.4999999999994) はなぜ1を返すのですか?
-
[解決済み】大文字・小文字を区別しない「Contains(string)
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】プロジェクトビルド時のエラー。エディタでスクリプトにコンパイルエラーがあるため、Playerのビルドにエラーが発生する
-
[解決済み】バックスラッシュを含むパス文字列のエスケープシーケンスが認識されない件
-
[解決済み】クロススレッド操作が有効でない。作成されたスレッド以外のスレッドからアクセスされたコントロール
-
[解決済み】取り消せないメンバはメソッドのように使えない?
-
[解決済み】C# - パスに不正な文字がある場合
-
[解決済み] 'IEnumerable<SelectListItem>' 型の ViewData アイテムで、キーが国であるものは存在しない。
-
[解決済み】EF 5 Enable-Migrations : アセンブリにコンテキストタイプが見つかりませんでした
-
[解決済み】Swashbuckle/Swagger + ASP.Net Core: "Failed to load API definition" (API定義の読み込みに失敗しました
-
[解決済み】エラー「必要なフォーマルパラメータに対応する引数が与えられていない」を解決する?
-
[解決済み】データが存在しないのに読み込もうとする試みが無効である