int main()
{
float x = k ; // k is some fixed positive value
while(x>0)
x-- ;
return 0 ;
}
上記のプログラムは無限ループできますか?C++のwhileループでの浮動小数点エラー
int main()
{
float x = k ; // k is some fixed positive value
while(x>0)
x-- ;
return 0 ;
}
上記のプログラムは無限ループできますか?C++のwhileループでの浮動小数点エラー
はいそれが可能です。一例として最大フロートを取る。
このコードは最大フロートm
ため、図示するように、m
はm - 1
に等しい:
#include <iostream>
#include <limits>
int main() {
auto m = std::numeric_limits<float>::max();
auto l = m;
l--;
std::cerr << (m == l) << "\n";
}
したがって、この開始値と、ループが無限大となります。
なぜですか?
float
は(他のすべての組み込み型と同様に)限定精度を持っています。 x
以外の数でx - 1
表現を作るために、x
よりも最大数の少ない間の差は2
が今度はm
、最大フロートとx
、ある最大のフロートとの差を計算させるよりも小さくなければなりません厳密に小さいm
より:
#include <iostream>
#include <cmath>
#include <limits>
int main() {
auto m = std::numeric_limits<float>::max();
std::cout << "float max: " << m << "\n";
auto x = std::nextafter(m, 0.0f);
std::cout << "biggest value less than max: " << x << "\n";
auto d = m - x;
std::cout << "the difference: " << d << "\n";
}
、これら二つの数間2.02824e+31
の大きなギャップがあり、判明しました。 1よりもはるかに大きい.1は小さすぎて違いを生むことはできない。
実際はできると思います。 k
が十分な大きさであれば、丸めはあなたの減少分を奪います。
はいできます。 k
が例えばFLT_MAX
である場合。このような大きな数字の間にこのような小さな距離を処理するのに十分な精度はありません。
#include <float.h>
#include <stdio.h>
int main()
{
float a = FLT_MAX;
float b = a - 1;
printf("%.10f\n", a - b);
return 0;
}
出力:
0.0000000000
そうしてはいけません。 – thokra
私はそれが起こるかもしれないいくつかの値があると思います。インタビューの問題でした。私は確信していません。 – Hellboy
@JoachimPileborg C++で定義されていない動作では、これらのタイプの質問をする必要があります。 – Caesar