int main()
{
float x = k ; // k is some fixed positive value
while(x>0)
x-- ;
return 0 ;
}
Kann über Programm in Endlosschleife gehen?Gleitkommafehler in der While-Schleife in C++
int main()
{
float x = k ; // k is some fixed positive value
while(x>0)
x-- ;
return 0 ;
}
Kann über Programm in Endlosschleife gehen?Gleitkommafehler in der While-Schleife in C++
Ja, es ist möglich. Nehmen Sie als Beispiel den maximalen Float.
Wie dieser Code zeigt, für den größten Schwimmer m
, m
gleich m - 1
:
#include <iostream>
#include <limits>
int main() {
auto m = std::numeric_limits<float>::max();
auto l = m;
l--;
std::cerr << (m == l) << "\n";
}
Demo: http://ideone.com/Wr9zdN
daher mit diesem Startwert, wird die Schleife unendlich sein.
Warum ist das?
float
hat (wie jeder andere eingebaute Typ) eine begrenzte Genauigkeit. Um x - 1
darstellbare von einer anderen Zahl als x
, die Differenz zwischen der größten Zahl kleiner als x
muss kleiner sein als 2.
Nun wollen ihnen den Unterschied zwischen m
berechnen, dem maximalen Schwimmer und x
, der größten Schwimmer, das ist streng weniger als 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";
}
Demo: http://ideone.com/VyNgtE
es stellte sich heraus, gibt es eine riesige Lücke von 2.02824e+31
zwischen diesen beiden Zahlen ist. Weit größer als 1. 1 ist einfach zu klein, um einen Unterschied zu machen.
Ich denke, es kann tatsächlich. Wenn k
groß genug ist, verschlingt die Rundung Ihr Dekrement.
Ja kann es. Wenn k
ist FLT_MAX
zum Beispiel. Es gibt nicht genug Präzision, um so kleine Entfernungen zwischen so großen Zahlen zu bewältigen.
#include <float.h>
#include <stdio.h>
int main()
{
float a = FLT_MAX;
float b = a - 1;
printf("%.10f\n", a - b);
return 0;
}
Ausgang:
0.0000000000
Sie sind richtig :), einen Link @ Hinzufügen [Codepade: unendlicher-loop] (http://codepad.org/xgn46vst) –
am Ausgang der Differenz Unter Berufung keine gute Idee ist, könnte es sein, ein Fehler darin. Einfach auf Gleichheit prüfen. Dies bestätigt die bitweise Gleichheit. – stefan
Ich war zwar ein besserer Weg zu demonstrieren, dass es nicht 1 war wie erwartet, sondern 0. – detunized
Es sollte nicht so sein. – thokra
Ich denke, es gibt einige Werte, wo es passieren kann. Es war ein Interview-Problem. Ich bin mir allerdings nicht sicher. – Hellboy
@JoachimPileborg Mit all dem undefinierten Verhalten in C++ sollten diese Art von Fragen gestellt werden. – Caesar