2016-07-16 14 views
1

I war der Unterschied zwischen log(3) herauszufinden und log10(3), mit diesem Code:Warum druckt std :: cout 4.9999999 als 5?

void testPrecisionError() { 
    cout 
    << log(243)/log(3) << " : " 
    << int(log(243)/log(3)) << " : " 
    << endl; 

    cout 
    << log10(243)/log10(3) << " : " 
    << int(log10(243)/log10(3)) << " : ") 
    << endl; 
} 

Der Ausgang ist:

5 : 4 // I think it is 4.999999 underlying 
5 : 5 

Ich fand heraus, dass als 4.9999995 ausgedruckt wird.

Warum druckt C++ es nicht wie 4.99999 wie Java?

Ich glaube, ich konnte nicht mehr cout, um mich davon zu überzeugen, dass es keinen PRÄZISIONSVERLUST gibt!

+5

Die Standard-Genauigkeit ist 6. –

+0

Warum nicht C++ es als 4.99999 wie Java ?? –

+0

4.99999 hat nur 5 Stellen der Genauigkeit, nicht 6 wie Standard C –

Antwort

0

Willkommen in der Welt der binären, wo reelle Zahlen nicht korrekt dargestellt werden können! double und float haben ein Präzisionsproblem. Sie müssen also vorsichtig sein, wenn Sie vergleichen 2 double Werte etc ...

Zum Beispiel:

  • sqrt(2) = [real value of sqrt(2)] +/- [precision error]
  • Genauigkeitsfehler hängen von der Art/CPU-Architektur Sie verwenden (double, float ...)
+0

Warum druckt C++ es nicht als 4.99999 wie Java ?? –

+0

Java kann eine andere Art von Darstellung für float/double Wert, die Genauigkeit ist besser als C (Verwendung der Klasse usw.) – Phong

+0

Java Verwendung IEEE 754 –

3

Weil es auf den nächsten Wert der letzten Ziffer der angeforderten Genauigkeit gerundet wird. Der tatsächliche Wert ist ungefähr:

4.99999999999999911182158029987 

Und mit 6 Ziffern der Präzision, das ist näher an 5.000000 als 4.999999, so zeigt es 5. Wenn Sie setprecision(16) oder höher verwenden, werden Sie alle 9 sehen.

Wenn Sie zu int umwandeln, wird es immer abgeschnitten, es wird nicht auf den nächsten Wert gerundet.

Warum, warum Java es als 4.999999 anzeigt, vielleicht wirft es nur zusätzliche Ziffern lieber als Rundung.

+0

Java zeigt es nicht als 4.999999 an Es zeigt es als 4.999999999999999 an. –

0

Fließkommaausgabe in Iostreams wird von precision des Streams gesteuert. Der Standard-IIRC ist 6 Stellen rechts von der Dezimalstelle. Wenn die siebte Ziffer eine 9 ist, rundet sie die sechste Ziffer auf und so weiter. In Ihrem Fall wird 4.9999999 ... zu 5.

Die maximale Dezimalgenauigkeit in IEEE 754, die Sie wahrscheinlich verwenden, liegt bei etwa 15 Dezimalstellen. Wenn Sie die Genauigkeit des Streams auf 16 oder so einstellen (mit dem setprecision Manipulator), sehen Sie "alle" Ziffern. Aber natürlich ist es nur eine Annäherung, denn das sind die Fließkommazahlen.

Warum ist es nicht wie Java? Zwei Sprachen, zwei Regelwerke. Ich würde argumentieren, dass Java falsch ist: Wenn die 7. Position 9 ist, dann ist 4.99999 um 0.0000009+ aus, während 5.0 nur um 0.0000001+ aus ist. Möchten Sie mehr Ziffern oder eine genauere Annäherung?