Concise and accurate double printing

I have double xone that I would like to print as a string s. I would like the view to obey the following properties:

  • Exact : absolute value (x - atof(s))less than epsilon
  • Brief : the presentation does not contain more significant digits than is required for an accurate

What is the best way to do this?

To illustrate why %fthey %gdon’t complete the tasks:

printf("%f\n", 1.0);              // 1.000000       not concise
printf("%g\n", 1.0);              // 1              good
printf("%f\n", 4357890.2342389);  // 4357890.234239 good
printf("%g\n", 4357890.2342389);  // 4.35789e+06    not accurate
+4
source share
3 answers

(cpplearner ) %.16g printf std::cout std:: setprecision :

#include <iostream>
#include <iomanip>

int main()
{
    std::cout << 4357890.2342389 << std::endl;

    std::cout << std::setprecision(16);

    std::cout << 4357890.2342389 << std::endl;
    std::cout << 1.0 << std::endl;

    std::cout << std::fixed;
    std::cout << "fixed\n";

    std::cout << 4357890.2342389 << std::endl;
}

:

4.35789e+06
4357890.2342389
1
fixed
4357890.2342389002442360

- link

: .

:

+4

, - , :

#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>

std::string concise_and_accurate( double x, int prec ) {
    // print the number to a stringstream with all the figures needed
    std::stringstream strnum;
    strnum << std::fixed << std::setprecision(prec) << x;
    std::string str = strnum.str();
    // cancel the extra zeroes at the right
    str.erase( str.find_last_not_of('0') + 1, std::string::npos );
    // delete the '.' if there are no other digits at the right
    if ( str[str.size()-1] == '.' ) str.erase(str.size()-1);
    return str; 
}


int main() {
    double test[] = { 4357890.2342389, 1.0, 1.0/3, 100.0/3 };

    for ( auto x : test ) {
        std::cout << concise_and_accurate(x,6) << '\n';
    }

    return 0;
}

:

4357890.234239
1
0.333333
33.333333
+1

, , :

C

++, :

#include <iostream>

std::cout << double(1.0) << std::endl
std::cout << 1.0 << std::endl
std::cout << double(4357890.2342389) << std::endl    
std::cout << 4357890.2342389 << std::endl

,

std::cout << std::setw(32) << std::setprecision(16) << double(1.0);

.

0
source

Source: https://habr.com/ru/post/1625877/


All Articles