std::numeri...max_digits10(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

okay bestie, welcome to the std::numeri...max_digits10(3) page from the C++ Standard Libary β€” yes, that's the manual name in the header, spelling and all 🫢.

🌸 NAME 🌸

std::numeric_limits::max_digits10 β€” std::numeric_limits::max_digits10. That's literally the whole NAME line: std::numeric_limits::max_digits10 - std::numeric_limits::max_digits10 πŸ’….

✨ Synopsis ✨

Here's the signature, no cap:

static constexpr int max_digits10  (since C++11)

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. And yes, she's static constexpr int, and she's been around since C++11 πŸ‘‘.

πŸŽ€ Standard specializations πŸŽ€

Vibe check for every T, bestie β€” this is the value of std::numeric_limits<T>::max_digits10:

  • /* non-specialized */ β€” 0
  • bool β€” 0
  • char β€” 0
  • signed char β€” 0
  • unsigned char β€” 0
  • wchar_t β€” 0
  • char8_t (since C++20) β€” 0
  • char16_t β€” 0
  • char32_t β€” 0
  • short β€” 0
  • unsigned short β€” 0
  • int β€” 0
  • unsigned int β€” 0
  • long β€” 0
  • unsigned long β€” 0
  • long long β€” 0
  • unsigned long long β€” 0
  • float β€” FLT_DECIMAL_DIG or std::ceil(std::numeric_limits<float>::digits * std::log10(2) + 1)
  • double β€” DBL_DECIMAL_DIG or std::ceil(std::numeric_limits<double>::digits * std::log10(2) + 1)
  • long double β€” DECIMAL_DIG or LDBL_DECIMAL_DIG or std::ceil(std::numeric_limits<long double>::digits * std::log10(2) + 1)

πŸ’€ Notes πŸ’€

Here's the part that's lowkey iconic: unlike most mathematical operations, the conversion of a floating-point value to text and back is exact as long as at least max_digits10 were used (9 for float, 17 for double). It is guaranteed to produce the same floating-point value, even though the intermediate text representation is not exact. It may take over a hundred decimal digits to represent the precise value of a float in decimal notation. No cap, the text can be a whole novel and still round-trip πŸ’–.

🌈 Example 🌈

Run this code, bestie β€” it's giving precision receipts 🧾:

#include <cmath>
#include <iomanip>
#include <iostream>
#include <limits>
#include <sstream>

int main()
{
    float value = 10.0000086;

    constexpr auto digits10 =
        std::numeric_limits<decltype(value)>::digits10;
    constexpr auto max_digits10 =
        std::numeric_limits<decltype(value)>::max_digits10;
    constexpr auto submax_digits10 = max_digits10 - 1;

    std::cout << "float:\n"
                 "       digits10 is " << digits10 << " digits\n"
                 "   max_digits10 is " << max_digits10 << " digits\n"
                 "submax_digits10 is " << submax_digits10 << " digits\n\n";

    const auto original_precision = std::cout.precision();
    for (auto i = 0; i < 5; ++i)
    {
        std::cout
            << "   max_digits10: " << std::setprecision(max_digits10) << value << "\n"
               "submax_digits10: " << std::setprecision(submax_digits10) << value
            << "\n\n";

        value = std::nextafter(value,
            std::numeric_limits<decltype(value)>::max());
    }
    std::cout.precision(original_precision);
}

Output:

float:
       digits10 is 6 digits
   max_digits10 is 9 digits
submax_digits10 is 8 digits

   max_digits10: 10.0000086
submax_digits10: 10.000009

   max_digits10: 10.0000095
submax_digits10: 10.00001

   max_digits10: 10.0000105
submax_digits10: 10.00001

   max_digits10: 10.0000114
submax_digits10: 10.000011

   max_digits10: 10.0000124
submax_digits10: 10.000012

πŸ¦‹ See also πŸ¦‹

  • radix β€” the radix or integer base used by the representation of the given type. [static] (public static member constant)
  • digits β€” number of radix digits that can be represented without change. [static] (public static member constant)
  • digits10 β€” number of decimal digits that can be represented without change. [static] (public static member constant)
  • min_exponent β€” one more than the smallest negative power of the radix that is a valid normalized floating-point value. [static] (public static member constant)
  • max_exponent β€” one more than the largest integer power of the radix that is a valid finite floating-point value. [static] (public static member constant)

mwah πŸ’‹ β€” footer vibes, preserved for the group chat: source/version/date is http://cppreference.com, 2024.06.10, and the page is std::numeri...max_digits10(3). That's it bestie, she's iconic, periodt. 🌟

πŸ“¦ where this page comes from