最終更新日時(UTC): 2025年09月27日 16時03分34秒
Raclamusi が更新

履歴 編集

variable
<limits>

# std::numeric_limits::max_digits10(C++11)

    static constexpr int max_digits10;

## 概要

`max_digits10`は、`T`が浮動小数点数型のとき意味を持つ。

基数`radix`の浮動小数点数を、仮数部がn桁で基数10の浮動小数点数に変換してまた元の基数`radix`の浮動小数点数に変換することを考える。
`max_digits10`は、上の変換によって元の浮動小数点数の値が変化しないようなnのうち、最小のものを表す。

通常、浮動小数点数を文字列などに変換する場合には出力精度 (小数点以下の桁数) として`digits10` (デフォルト) を使用すれば十分である。しかしその精度では、下位数ビットが異なる値を同値とみなしてしまう場合がある。`max_digits10`を出力精度として使用することで、そのような値の違いに気づくことができる。

`max_digits10`は `digits` を用いて次のように計算できる：

`(Is radix power of 10) ? digits * log10(radix) : ceil(1 + digits * log10(radix))`

対応するマクロを次の表に挙げる。

型 | 対応するマクロ
--- | ---
`float` | `FLT_DECIMAL_DIG`
`double` | `DBL_DECIMAL_DIG`
`long double` | `LDBL_DECIMAL_DIG`

なお、`is_specialized == false`もしくは浮動小数点数型以外の場合、`max_digits10`は`0`となる。

## 例

    #include <iostream>
    #include <limits>
    #include <cmath>
    #include <sstream>
    #include <bitset>
    #include <cstring>

    std::string make_float_string(float f, int digits) {
      std::stringstream s;
      s.precision(digits);
      s << std::scientific << f;
      return s.str();
    }

    std::uint32_t float_to_uint(float f) {
        std::uint32_t result = 0;
        std::memcpy(&result, &f, sizeof(std::uint32_t));
        return result;
    }

    std::string make_bit_string(float f) {
        return std::bitset<32>(float_to_uint(f)).to_string();
    }

    int main()
    {
      using limits = std::numeric_limits<float>;

      std::cout << "float digits10 : " << limits::digits10 << std::endl;
      std::cout << "float max_digits10 : " << limits::max_digits10 << std::endl;
      std::cout << std::endl;

      // digits10とmax_digits10での、
      // 下位数ビットが異なる浮動小数点数の出力のされ方を比較
      for (int digits : {limits::digits10, limits::max_digits10}) {
        std::cout << "[digits : " << digits << ']' << std::endl;
        std::cout << make_float_string(3.145900f, digits) << std::endl;
        std::cout << make_float_string(std::nextafter(3.145900f, 1.0f), digits) << std::endl;
      }

      // それぞれの値のビット列を出力
      std::cout << "[bit string]" << std::endl;
      std::cout << make_bit_string(3.145900f) << std::endl;
      std::cout << make_bit_string(std::nextafter(3.145900f, 1.0f)) << std::endl;
    }

### 出力例

    float digits10 : 6
    float max_digits10 : 9

    [digits : 6]
    3.145900e+00
    3.145900e+00
    [digits : 9]
    3.145900011e+00
    3.145899773e+00
    [bit string]
    01000000010010010101011001101101
    01000000010010010101011001101100

## バージョン

### 言語

- C++11

### 処理系

- Clang: 3.0 ✅
- GCC: 4.5.4 ✅
- ICC: ?
- Visual C++: 2010 ✅, 2012 ✅, 2013 ✅, 2015 ✅, 2017 ✅

### 参照

- A Proposal to add a max significant decimal digits value to the C++ Standard Library Numeric limits