Visual Studio-Compiler-Optimierung für das Typcasting in C ++

8

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.

    
TheBlueNotebook 29.02.2016, 09:41
quelle

2 Antworten

1

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.

    
Bathsheba 29.02.2016 09:46
quelle
0

b * 1000 ist int * int , es tritt also eine ganzzahlige Multiplikation auf und es besteht ein höheres Risiko eines Überlaufs. (Überlauf in vorzeichenbehafteter arithmetischer Ganzzahl ist undefiniertes Verhalten )

Casting b bis float wird auch das lösen.

%Vor%     
MikeCAT 29.02.2016 09:44
quelle