Ich hatte die folgende Anweisung im Code:
%Vor% wobei b
auch int
ist,
und c
ist ein unsigned int
mit einem konstanten Wert (von 15 in meinen Testläufen)
Diese Anweisung befand sich innerhalb einer while-Schleife, in der b
bei jeder Iteration um 1 erhöht wird.
Dieser Code funktionierte gut, bis ich beschloss, die Optimierungsflags in Visual Studio zu aktivieren (Geschwindigkeit maximieren). Danach würde a
zufällig in einen Überlauf laufen (d. H. Es hätte einen Wert von -2147483647
). Bei weiteren Untersuchungen trat dieser Überlauf bei verschiedenen Werten von b
auf. Die Werte von b, bei denen der Überlauf stattfand, lagen in den Testläufen, die ich beobachtete, zwischen 9 und 12.
Was das Problem gelöst hat, war die kleine Änderung wie unten dargestellt:
%Vor%Irgendwelche Ideen, wie hat das geholfen? Es funktioniert gut, aber ich kann nicht herausfinden, warum?
Bearbeiten: Hinzufügen weiterer Informationen basierend auf Kommentaren:
Beim Protokollieren habe ich Folgendes festgestellt:
(float)(b * 1000) / (float)c + .5f
wurde auf einen wirklich großen Wert ausgewertet, der beim Übergeben an int
zum Überlauf führte. Individuell wurden float(b*1000)
und float(c)
jedoch korrekt berechnet.
b * 1000
überläuft höchstwahrscheinlich den int
type; Das Verhalten ist undefiniert .
Lösche alle diese verschleiernden Zauber und benutze
b * 1000.0 / c + 0.5
stattdessen. 1000.0
ist ein double
literal und bewirkt, dass der erste Term im Fließkomma ausgewertet wird.
Sie sollten die Größe des Ausdrucks überprüfen, bevor Sie zurück in int
konvertieren, insbesondere wenn c
klein ist. std::numeric_limits
ist dafür nützlich.
Tags und Links c++ visual-studio compiler-optimization