2015-06-30 12 views
6

Ich habe ein C++ - Programm, das unter Windows/Linux ausgeführt wird. Unter Windows wird das Programm mit Visual Studio 2012 kompiliert und Linux mit GCC kompiliert. Wenn verdoppelt Strings sprintf Visual Studio Umwandlung wird für Verbindungen eine andere Rundungsmethode als der GCC-Compiler - dh Dezimalzahlen in einem Compiler 5.C++ Rundungsverhalten Konsistenz für Bindungen mit Sprintf

Visual Studio beenden erscheint round half away from zero auszuführen, während GCC round even aka Banker tut Runden.

Runde ist sogar das gewünschte Verhalten.

Kann das Rundungsverhalten für Sprintf-Format-Strings in Visual Studio/Windows geändert werden? Da muss ich die Rundung konsequent zwischen den beiden verhalten.

Hier ist eine kleine Probe C++ Programm, das das oben beschriebene Verhalten zeigt:

int main() 
{ 
    char buffer[100]; 

    double x; 
    for (x = -0.5; x <= 10.5; x += 1.0) 
    { 
     sprintf(buffer,"%4g %.0f\n", x, x); 

     std::cout << buffer; 
    } 

    return 0; 
} 

Windows-Ausgang. Zahlen sind gerundet, weg von Null:

windows

OSX Ausgabe mit xCode zusammengestellt. Zahlen sind gerundet Verwendung rund sogar in Richtung der geraden Zahl:

osx

Ausgang OSX:

+1

Sie könnten in diesem Artikel, und seine Kommentare aussehen wollen: http://www.exploringbinary.com/inconsistent-rounding-of-printed-floating-point-numbers/ – NathanOliver

+0

Sie immer Ihre eigene {*} printf verwenden können Funktionen – technosaurus

+0

[Rundungsunterschiede auf Windows vs Unix-basierten System in Sprintf] (http://stackoverflow.com/q/4649554/995714) –

Antwort

2

Dies ist definiert Umsetzungsverhalten aus dem Entwurf C11 Standardabschnitt 7.21.6.1 Die fprintf Funktion, die sprintf Bezug für Formatbezeich deckt und auch C++, da der C++ Standard auf dem C-Standard für stdio Funktionen beruht, heißt es für die f Formatbezeichner:

der Wert auf 01 gerundet wirddie entsprechende Anzahl von Ziffern.

dies auch durch defect report 211 bedeckt ist, die addierten folgende:

Die Genauigkeit der Gleitkommaoperationen (+, -, *, /) und der Bibliotheksfunktionen in und dieser Rückkehr Floating -Point-Ergebnisse ist die Implementierung definiert, ebenso wie die Genauigkeit der Konvertierung zwischen internen Gleitkomma-Repräsentationen und String-Repräsentationen, die von der libray-Routine in und ausgeführt werden. Die Implementierung kann angeben, dass die Genauigkeit unbekannt ist.

der Artikel Inconsistent Rounding of Printed Floating-Point Numbers deckt diese Inkonsistenz in großen Details und erwähnt, dass:

glibc printf() den aktuellen IEEE-Rundungsmodus zu berücksichtigen, wurde aktualisiert. Dies wurde in Version 2.17 getan; Ich habe es gerade in Version 2.18 getestet. Bei dieser Vorgehensweise ist natürlich eine Rundum-Rund-Halb-Null-Entfernung immer noch keine Option, daher hilft dies nicht, die Ausgabe konsistent mit anderen Plattformen zu machen.

aber wie gesagt, dies hilft nicht mit Cross-Plattform-Konsistenz.