pow () in Ganzzahl umgewandelt, unerwartetes Ergebnis

8

Ich habe einige Probleme mit der Verwendung einer Ganzzahl für die Funktion pow() in der Programmiersprache C. Der Compiler, den ich verwende, ist der Tiny C Compiler (tcc Version 0.9.24) für die Windows-Plattform. Wenn der folgende Code ausgeführt wird, wird das unerwartete Ergebnis 100, 99 :

ausgegeben %Vor%

Bei diesem Online-Compiler ist die Ausgabe jedoch wie erwartet: 100, 100 . Ich weiß nicht, was dieses Verhalten verursacht. Irgendwelche Gedanken? Programmierfehler von mir, Compilerfehler?

    
Jori 24.08.2013, 10:54
quelle

3 Antworten

2

Sie haben einen Fehler in tcc gefunden. Dank dafür. Der Patch wurde soeben an das Repository übergeben. Es wird in der nächsten Version enthalten sein, aber das könnte eine Weile dauern. Sie können natürlich die Quelle ziehen und selbst bauen. Der Patch ist hier

Ссылка

    
mikijov 28.08.2013, 21:14
quelle
6

Einige Untersuchungen im Assemblercode. (OllyDbg)

%Vor%

Der zugehörige Assembly-Abschnitt:

%Vor%

Der generierte Code für zwei Aufrufe ist der gleiche, aber die Ausgaben sind unterschiedlich. Ich weiß nicht, warum tcc FLDCW dorthin gestellt hat. Aber der Hauptgrund für zwei verschiedene Werte ist diese Zeile.

Vor dieser Zeile ist die Runde Mantissa Precision Control Bits 53bit (10), aber nach Ausführung dieser Zeile (sie lädt die FPU-Registersteuerung) wird sie auf 64Bits (11) gesetzt. Auf der anderen Seite Rundungskontrolle ist nächste so 99.999999999999999990 ist das Ergebnis. Lesen Sie mehr ...

Lösung:

Nachdem Sie (int) zum Umwandeln von float in int verwendet haben, sollten Sie diesen numerischen Fehler erwarten, da bei diesem Casting die Werte zwischen [0, 1) und 0 abgeschnitten werden.

Angenommen, die 10 2 ist 99,99999999999. Nach diesem Cast ist das Ergebnis 99.

Versuchen Sie, das Ergebnis zu runden, bevor Sie es in eine Ganzzahl umwandeln, zum Beispiel:

%Vor%

    
deepmax 24.08.2013 18:57
quelle
0

Es scheint, dass sich die Rundungsmethode ändern kann und somit ein ASM-Befehl finit erforderlich ist, um die FPU zurückzusetzen. In FreeBASIC unter Windows bekomme ich 99.9999 schon beim ersten Versuch, und so denke ich für dich nach dem ersten Versuch wäre es ein konsistentes 99.9999 . (Aber ich nenne dieses undefinierte Verhalten tatsächlich mehr als einen Fehler in der% c_de% der C-Laufzeitumgebung.)

Also mein Ratschlag ist nicht die Konvertierung mit Abrundung. Um solche Probleme zu vermeiden, verwenden Sie zum Beispiel:

pow()

    
Mysoft 24.08.2013 20:27
quelle

Tags und Links