6
votes

Can I specify setprecision to round double values when stream to std output?

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

Output: 0.756247615801

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

Output: 0.756248

But I need the output as 0.756247

Thanks

4

4 Answers

17
votes

There is also std::fesetround from <cfenv>, which sets the rounding direction:

#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";
}

(note that these are not the kind of comments I recommend, they are just for tutoring purposes)

Output:

desired: 0.756247
default: 0.756248

Important note, though: I did not find any mention in the standard, that the operator<< overloads for floating types have to honour the rounding direction.

2
votes

Another approach is to defeat the rounding by subtracting, in your second case, 0.000005 from the double before outputting it:

total_run_time / TIME - 0.000005

In many ways I prefer this as it avoids the potential for integer overflow.

2
votes

Multiply the result of your division by a million, convert to an integer, and divide by a million (as a double). Have the side-effect that std::setprecision is not needed for the output.

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

It looks really dirty, but it works!