2013-10-17 7 views
10
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++

+0

Es sollte nicht so sein. – thokra

+0

Ich denke, es gibt einige Werte, wo es passieren kann. Es war ein Interview-Problem. Ich bin mir allerdings nicht sicher. – Hellboy

+3

@JoachimPileborg Mit all dem undefinierten Verhalten in C++ sollten diese Art von Fragen gestellt werden. – Caesar

Antwort

14

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.

4

Ich denke, es kann tatsächlich. Wenn k groß genug ist, verschlingt die Rundung Ihr Dekrement.

5

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 
+0

Sie sind richtig :), einen Link @ Hinzufügen [Codepade: unendlicher-loop] (http://codepad.org/xgn46vst) –

+1

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

+1

Ich war zwar ein besserer Weg zu demonstrieren, dass es nicht 1 war wie erwartet, sondern 0. – detunized