最近、私は記事を読んでいた。 理解:ダブルまたはナッシング
int main()
{
double x = 1e8;
while(x > 0)
{
--x;
}
}
は、このコードが実行されることを想定します
Double or Nothing from GOTW by Herb Sutter 私は、次のプログラムの説明と少し混乱しています一部のマシンでは1秒です。私はこのようなコードがばかげているという点に同意します。
x
をfloat
からdouble
に変更すると、問題の説明によれば、一部のコンパイラではコンピュータの動作が永久に維持されます。説明は、標準からの次の引用に基づいています。
ある3つの浮動小数点型:ダブルフロート、ダブル長いセクションC++標準の3.9.1/8から引用
。 double型はfloat以上の精度を提供し、long型doubleは少なくともdoubleと同じ精度を提供します。 float型の値のセットは、double型の値の集合のサブセットです。 double型の値のセットは、long double型の値の集合のサブセットです。
コードについての質問です:
あなたが「フロート」と「ダブル」に変更した場合、それが取ることを期待するどのくらい?どうして?ここで
は、与えられた説明です:
それはおそらくどちらかの約1秒かかります(特定の実装の山車の上には、多少速く早く、または倍よりやや遅くなることがあります)、または永遠にfloatが0から1e8までのすべての整数値を正確に表すことができるかどうかによって異なります。
上記の標準からの引用は、doubleで表すことができるがfloatで表現できない値がある可能性があることを意味します。特に、一般的なプラットフォームやコンパイラでは、doubleは[0,1e8]のすべての整数値を正確に表現できますが、浮動小数点はできません。
floatが0から1e8までのすべての整数値を正確に表すことができない場合はどうなりますか?次いで、修飾されたプログラムがダウンカウントを開始しますが、最終的には表現できない値Nに達するとのためにN-1 == N(不足浮動小数点精度まで)...と
私の質問は:
floatが1e8
を表すことさえできない場合は、float x = 1e8
を初期化するときにすでにオーバーフローしているはずです。どうすればコンピュータを永遠に稼働させることができますか?
これは、コンパイラがint
タイプで与えられた数を表すことができない場合、それはオーバーフローをもたらすであろうことを意味
#include <iostream>
int main()
{
int a = 4444444444444444444;
std::cout << "a " << a << std::endl;
return 0;
}
It outputs: a -1357789412
(ないdouble
しかしint
が)私はここに簡単な例を試してみました。
私は誤解しましたか?私が見逃した点は何ですか? x
がdouble
からfloat
に変更されていますか?
ありがとうございました!
すてきな情報ありがとう、私の質問はなぜ初期化時にオーバーフローがある場合は、whileループも開始されますか? – taocp
@taocp初期化時にオーバーフローが発生していません。浮動小数点形式は、+ 1に達するまで、より高い値に行くにつれて*精度*が連続的に低くなります。無限の&#NANの操作は正当であり、未定義ではありません。彼らは予期しない結果をもたらすかもしれません。 [IEEE-754標準](https://en.wikipedia.org/wiki/IEEE_floating_point)をご覧ください。 –
@indeterminatelysequencedああ、ありがとうございます。 – taocp