2013-11-28 11 views
5

Kann ich setprecision angeben, um doppelte Werte zu runden, wenn der Stream an die Standardausgabe ausgegeben wird?Wie setze ich die Genauigkeit der Rundung ein?

ofile << std::setprecision(12) << total_run_time/TIME << "\n"; 

Ausgang: 0,756247615801

ofile << std::setprecision(6)<< total_run_time/TIME << "\n"; 

Ausgang: 0,756248

Aber ich brauche die Ausgabe als 0.756247

Dank

Antwort

14

Es gibt auch std::fesetround von <cfenv>, die die Rundung Richtung setzt:

#include <iostream> 
#include <iomanip> 
#include <cmath> 
#include <cfenv> 

int main() { 
    double runtime = 0.756247615801; 

    // Set rounding direction and output with some precision: 
    const auto prev_round = std::fegetround(); 
    std::fesetround(FE_DOWNWARD);  
    std::cout << "desired: " << std::setprecision(6) << runtime << "\n"; 

    // Restore previous rounding direction and output for testing: 
    std::fesetround(prev_round); 
    std::cout << "default: " << std::setprecision(6) << runtime << "\n"; 
} 

(beachten Sie, dass diese nicht die Art von Bemerkungen Ich empfehle, sie sind nur für Nachhilfe Zwecke)

Ausgang:

desired: 0.756247 
default: 0.756248 

Wichtiger Hinweis, t hough: Ich fand keine Erwähnung in der Norm, dass die operator<< Überladungen für Floating-Typen haben, um die Rundungsrichtung zu beachten.

+0

Die einzige 100% korrekte Lösung bisher, unter der Annahme einer Qualitätsimplementierung, wo die Funktionen zur Dezimalzählung den Rundungsmodus berücksichtigen. –

+0

@PascalCuoq: Ich habe den Teil mit dem Namen 'Wichtiger Hinweis, obwohl' –

+0

hinzugefügt @phreshel' fesetround' gibt "Zero, wenn die angeforderte Rundungsrichtung wurde erfolgreich festgelegt. Andernfalls, ein Wert ungleich Null": http: // www. cplusplus.com/reference/cfenv/fesetround/#return Ich glaube, du wolltest verwenden: ['fegetround'] (Ich habe mir die Freiheit genommen, deine Antwort zu bearbeiten) . Fühlen Sie sich frei, Rollback, wenn meine Bearbeitung keinen Sinn ergibt. –

2

Multiplizieren Sie das Ergebnis Ihrer Division mit einer Million, konvertieren Sie sie in eine ganze Zahl und dividieren Sie sie durch eine Million (als Doppel). Habe den Nebeneffekt, dass std::setprecision für die Ausgabe nicht benötigt wird.

+2

+1, aber offensichtlich wird es Sie in diesem Fall nicht beeinflussen, aber achten Sie immer darauf, dass Ihre Integer nicht überläuft. – Bathsheba

+0

Dies wird erst nach 35.79 Minuten überlaufen (Genauer gesagt, wenn Ihre Integer 32bit ist, geben Sie undefiniertes Verhalten ein (in der Praxis höchstwahrscheinlich Überlauf) für total_run_time> = 2147.5.) –

+1

Vermeiden Sie die Konvertierung in 'int' (und den daraus resultierenden möglichen Überlauf) indem man 'modf' verwendet (was ein' double' in seine Integral- und Bruchteile zerlegt). –

2

Ein weiterer Ansatz ist die Rundung durch Subtraktion, im zweiten Fall zu besiegen, 0,000005 vom double, bevor sie ausgegeben:

total_run_time/TIME - 0.000005 

In vielerlei Hinsicht ich das lieber als es das Potenzial für Integer-Überlauf vermeidet.

+4

Aber führt mögliche Rundungsfehler ein, da '0.000005' nicht genau darstellbar ist. –

1
std::cout.write(std::to_string(0.756247615801).c_str(), 8); 

Es sieht wirklich dreckig aus, aber es funktioniert!

+0

Sie könnten es besser machen und verwenden 'std :: string :: substring (0,9)' –

+0

std :: string :: substr erstellt ein zusätzliches String-Objekt, das nicht benötigt wird, also habe ich nur geschrieben, um den relevanten Teil auszugeben . –

+0

Ich dachte nur, es wäre eine bessere Selbstdokumentation, aber du hast Recht. –

Verwandte Themen