2016-07-29 8 views
3

Ich habe den folgenden Code auf Mac versucht, die Ausgabe ist irgendwie seltsam für mich.C++ anderes Druckverhalten zwischen Werten und Variablen

float a = 2.225; 
float b = 123.235; 
printf("round: %.2f %.2f \n", a, b); 
printf("round: %.2f %.2f \n", 2.225, 123.235); 

Ausgang:

round: 2.22 123.24 
round: 2.23 123.23 

g ++ --version

Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/usr/include/c++/4.2.1 
Apple LLVM version 7.3.0 (clang-703.0.31) 
Target: x86_64-apple-darwin15.5.0 
Thread model: posix 
InstalledDir: /Library/Developer/CommandLineTools/usr/bin 

Was die Rundungsregeln in Druck sind? Wie kann ich in diesen beiden Situationen das gleiche Druckergebnis erzielen? Vielen Dank.

+10

Ich denke der Unterschied ist zwischen 'float's und' double's. –

+0

Gelesen http://floating-point-gui.de/ –

+2

Das Problem ist nicht im Drucken - Sie erhalten unterschiedliche Ausgabe, weil Sie unterschiedliche Eingabe übergeben. Im ersten Fall verlieren Sie die Genauigkeit in dem Moment, in dem Sie 'float' Variablen' double' Werte zuweisen. –

Antwort

6

Die erste printf() konvertiert die float Werte in double und druckt dann die Ergebnisse. Beachten Sie, dass die Initialisierungen die Konstanten double in float konvertieren. Die Sekunde übergibt die double Werte direkt. Sie können float Konstanten mit dem Suffix F angeben - aber die Regeln von C konvertieren noch diese float Konstanten zu double vor dem tatsächlichen Aufruf printf() wegen der Standard-Argument-Promotion-Regeln.

#include <stdio.h> 

int main(void) 
{ 
    float a = 2.225; 
    float b = 123.235; 
    printf("round: %.2f %.2f\n", a, b); 
    printf("round: %.2f %.2f\n", 2.225, 123.235); 
    printf("round: %.2f %.2f\n", 2.225F, 123.235F); 

    return 0; 
} 

Ausgang:

round: 2.22 123.24 
round: 2.23 123.23 
round: 2.22 123.24 
4
2.225 

Das ist eine wörtliche, vom Typ double.

float a = 2.225; 

dass ein double zu einem float zuweist (Verlust Präzision, siehe unten).

printf("%.2f", ...); 

Dies druckt ein double (auch wenn Sie ein float als Parameter übergeben, die Förderung aufgrund Typs), mit einer Genauigkeit von zwei Stellen nach dem Komma.

float a = 2.225; 
printf("%.2f", a); 

Dies wird Zuweisen einer double zu a float, dann zurück zu einer double (Typ Förderung) Gießen, und das Bedrucken.

printf("%.2f", 2.225); 

Dieser druckt ein double (ohne der Rückwärts- und hergehende Guss).

Was sind die Rundungsregeln beim Drucken?

Rundung funktioniert so, wie Sie es erwarten würden, aber ist hier nicht Ihr Problem.

Der Unterschied in der Ausgabe geschieht, weil Ihre a und bfloat sind, die direkt bedruckten Literale sind nicht. Sie haben zufällig Werte ausgewählt, bei denen der Genauigkeitsverlust aufgrund des Float-Effekts einen Unterschied macht.

Wie kann ich in diesen beiden Situationen das gleiche Druckergebnis erzielen?

Verwenden Sie double konsistent.

double a = 2.225; 
double b = 123.235;