Wie verwende ich fälschlicherweise die Funktion round () in C?

7

Ich bekomme unerwartete Ergebnisse von den Funktionen round() und roundf() in der math.h -Bibliothek. Hier ist der Beispielcode:

%Vor%

Wenn ich das Programm kompiliere und laufe, bekomme ich:

%Vor%

Wierd huh?

Update: Zusammen mit den Antworten habe ich bestätigt, dass der Code auf einem neueren Compiler korrekt funktioniert. (Ich denke% lf ist nicht der richtige printf-Bezeichner, aber das hat in diesem Fall keinen Einfluss auf das Endergebnis.) Ich muss herausfinden, warum der Compiler sich so verhält, weil ich einen Code verwende, der round () und verwendet war Compiler auf der gleichen Maschine. Ich werde den Beitrag aktualisieren, wenn ich es herausgefunden habe.

%Vor%     
Harry 22.02.2009, 22:15
quelle

7 Antworten

10

Sie können scheitern, wenn Sie den Code kompilieren, ohne gcc mit dem C99-Modus zu kompilieren ( -std=c99 ), und ihm mitteilen, dass er nicht über spezielle eingebaute Funktionen Bescheid wissen soll (mit -fno-builtin ). Dann wird davon ausgegangen, dass Ihre Rund- / Rundungsfunktion als

definiert ist %Vor%

Weil es in der Zeit vor C99 noch keine solchen Funktionen gab, gibt es keine Deklaration und deklariert sie implizit. Und dies wird offensichtlich fehlschlagen, da die Aufrufseite den Rückgabewert als int behandelt, während die aufgerufene Seite (in der Definition dieser Funktionen in der verknüpften Bibliothek) einen Gleitkommawert zurückgibt. Ich erhalte diese Ergebnisse zum Beispiel:

%Vor%

Nicht, dass Sie jetzt denken, dass Sie den Rückgabewert in einen Float-Wert umwandeln könnten und in Ordnung wären. Nun, es ist schlimmer. Der Rückgabewert ist nicht einmal garantiert, etwas mit dem zurückgegebenen Float zu tun zu haben. Die call-side liest von einem Ort, der weiß, wo ganze Zahlen zurückgegeben werden. Aber Ihr Compiler kann Floats an einer anderen Stelle (z. B. in einem Gleitzeigerregister) von der Angerufenen Seite zurückgeben. Das obige könnte tatsächlich alles getan haben, einschließlich des Abbrechens des Programms, weil es sich in einer undefinierten Weise verhält.

Was können Sie also tun, damit es funktioniert? Übergeben Sie den Compiler das std=c99 -Flag oder verwenden Sie andere Möglichkeiten zum Runden (Floor ist einer von ihnen), die diese Funktionen nicht benötigen

%Vor%

Siehe die Hilfeseite von man 3 round . Wenn Sie jedoch einen sehr alten GCC haben - ich bin mir nicht sicher, ob er genug von C99 unterstützt, um diesen Schalter zu haben. Schauen Sie sich die Feature-Test-Makros an, die in der Manpage von round beschrieben sind.

    
Johannes Schaub - litb 22.02.2009, 22:37
quelle
3

Wenn ich diesen genauen Code kompiliere und ausführe (unter gcc auf cygwin) bekomme ich:

%Vor%

Wie neu ist dein Compiler? Ein Kompilierfehler ist alles, was ich mir vorstellen kann, da gcc -Wall auch keine Warnungen gibt.

Um weitere Informationen hinzuzufügen dieser Forum-Thread scheint sich ändernden Compiler auf eine neuere Version zu zeigen behebt es. Wenn dies für Sie nicht funktioniert, müssen Sie mehr Details zu Compiler und Betriebssystem angeben, aber da dies für andere Leute auf drei verschiedenen Plattformen zu funktionieren scheint, sieht es so aus, als wäre Ihr Compiler fehlerhaft.

    
Nick Fortescue 22.02.2009 22:23
quelle
2

Um dem Chor der Genehmigungen hinzuzufügen, funktioniert das für mich (OS X Leopard mit gcc).

Aus Neugier, müssen Sie die -lm Flagge verwenden? Ich habe nicht das erste Mal, und ich habe das zweite Mal, und es gab keinen Unterschied, aber das liegt daran, dass libm.dylib und libc.dylib sind symbolische Links zu der gleichen Bibliothek auf OS X. Vielleicht ist Ihre libm kaputt oder etwas? Müssen Sie mit libm verlinken oder nicht? Ich würde denken, dass die Math.h-Funktionen Teil der libc wären ...?

BEARBEITEN:

Bevor Sie irgendetwas davon tun, versuchen Sie stattdessen Folgendes:

%Vor%

Ich denke nicht, dass sich das ändern sollte, aber wenn es so ist, gewinne ich.

    
Chris Lutz 22.02.2009 22:24
quelle
2

Noch ein "funktioniert auf meinem Rechner" auf Ubuntu mit gcc Version 4.3.2.

%Vor%

Ich bekomme allerdings ein paar Warnungen, wenn ich kompiliere.

%Vor%     
Bill the Lizard 22.02.2009 22:34
quelle
2

litb war auf dem richtigen Weg. -std=c99 hat nicht funktioniert, aber das Hinzufügen von #define _ISOC99_SOURCE hat funktioniert. Der Code sieht also so aus:

%Vor%     
Harry 23.02.2009 06:45
quelle
1

Das hilft offensichtlich nicht, aber der Code sieht aus und läuft wie erwartet für mich. Alles scheint gut.

    
vinc456 22.02.2009 22:23
quelle
0

Sieht so aus, als ob Sie es richtig benutzen, beschreiben Sie Ihre Umgebung etwas?

    
Davy Wybiral 22.02.2009 22:37
quelle

Tags und Links