最終更新日時:
が更新

履歴 編集

十六進浮動小数点数リテラル(C++17)

概要

2を底とする、指数表記の十六進浮動小数点数リテラルがサポートされた。

仕様

十六進プレフィックス 仮数部 指数部 サフィックス

  1. 十六進プレフィックス: 0[xX]
    • 0x または 0X
  2. 仮数部: ([0-9a-fA-F]*\.[0-9a-fA-F]+|[0-9a-fA-F]+\.?)
    • 十六進整数部.十六進小数部
    • 十六進整数部.
    • .十六進小数部
    • 十六進整数
  3. 指数部 (底2): [pP][+-]?[0-9]+
    1. p または P
    2. 符号 + または - (任意)
    3. 十進数
  4. サフィックス: [flFL]?
    • f, F, l, L のいずれか (任意)
    • サフィックスを省略した場合はdouble型、fもしくはFを指定した場合はfloat型、lもしくはLを指定した場合はlong double型となる

0xSIGpEXP は $(\text{SIG})_{16} \times 2^{(\text{EXP})_{10}}$ である。 たとえば 0xABCp-3 は十進数で $(10 \times 16^2 + 11 \times 16 + 12) \times 2^{-3} = 343.5$ である。

十六進浮動小数点数リテラルには 桁区切り文字を使用できる。

十六進表記で浮動小数点数を出力するには、 std::ostream では std::hexfloatstd::printf では %a/%A を用いる。

std::strtod は十六進表記で浮動小数点数の入力を受け取る (が実際には機能しない; 詳細は備考参照)。

#include <iostream>

int main()
{
  std::cout << 0xABCp-3f << '\n';
  double dbl_min = 0x1.0p-1'022; // 1 * 2^-1022 (double の正の正規化数の最小値)
  std::cout << dbl_min << '\t' << std::hexfloat << dbl_min << '\n';
  return 0;
}

出力

343.5
2.22507e-308    0x1p-1022

この機能が必要になった背景・経緯

十六進リテラルによってある浮動小数点数を正確に表現することができるようになった。

備考

C

C99 で十六進浮動小数リテラルが採用された。

iostream の問題

std::strtodpP を認識しないため、十六進表記で浮動小数点数を受け取って適切に変換することができない (LWG issue 2381)。

参照