Full precision display of floating point numbers in C++?

后端 未结 3 1420
一个人的身影
一个人的身影 2021-01-19 12:48

I have read several topics about the display of floating point numbers display in C++ and I couldn\'t find a satisfying answer.

My question is: how

相关标签:
3条回答
  • 2021-01-19 13:39

    The value std::numeric_limits<double>::digits10 provides the number of decimal digits which can safely be restored, i.e., the number of decimal digits which survive a round-trip decimal->double->decimal. Assuming more decimal digits are correct isn't helpful. If you want to faciliate the round-trip double->decimal->double you'd use std::numeric_limits<double>::max_digits10.

    If you want the exact values you'd use std::numeric_limits<double>::digits but it will display numbers converted from decimal values in a funny way as they are normally rounded values. This is also the reason why max_digits10 isn't useful when presenting numbers for human consumption: the last couple of digits are normally not those expect by the human reader.

    0 讨论(0)
  • 2021-01-19 13:39

    In C++20 you'll be able to use std::format to do this:

    std::cout << std::format("{}", M_PI);
    

    Output (assuming IEEE754 double):

    3.141592653589793
    

    The default floating-point format is the shortest decimal representation with a round-trip guarantee. The advantage of this method compared to using the precision of max_digits10 from std::numeric_limits is that it doesn't print unnecessary digits. For example:

    std::cout << std::setprecision(
      std::numeric_limits<double>::max_digits10) << 0.3;
    

    prints 0.29999999999999999 while

    std::cout << std::format("{}", 0.3);
    

    prints 0.3 (godbolt).

    In the meantime you can use the {fmt} library, std::format is based on. {fmt} also provides the print function that makes this even easier and more efficient (godbolt):

    fmt::print("{}", M_PI);
    

    Disclaimer: I'm the author of {fmt} and C++20 std::format.

    0 讨论(0)
  • 2021-01-19 13:49

    Have you looked at std::max_digits10?

    From cppreference:

    The value of std::numeric_limits<T>::max_digits10 is the number of base-10 digits that are necessary to uniquely represent all distinct values of the type T, such as necessary for serialization/deserialization to text. This constant is meaningful for all floating-point types.

    The implication of this (and is how I use it) is that the text output can be copy/pasted into another program and the number will represent the same number.

    Now, I must say that my work-horse format is always right-justified %23.16E, and I use engineering judgement for the last few digits. I like it because is is sufficient for the sign, the exponent, and sixteen digits.

    -----------------------
    -1.1234567812345678E+12
    

    Now, notice that digits of precision and decimal digits of precision are not necessarily the same thing.

    0 讨论(0)
提交回复
热议问题