最終更新日時(UTC):
が更新

履歴 編集

variable
<limits>

std::numeric_limits::has_denorm(C++23で非推奨)

static const float_denorm_style has_denorm;     // (1) C++03
static constexpr float_denorm_style has_denorm; // (1) C++11

この機能は、C++23で非推奨となった。

概要

浮動小数点数型において、型Tの非正規化数(Denormal Number)のサポート状況を判定する。

非正規化数のサポート状況
std::denorm_indeterminate 許可するか判定できない
std::denorm_absent 許可しない
std::denorm_present 許可する

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

対応するマクロ
float FLT_HAS_SUBNORM
double DBL_HAS_SUBNORM
long double LDBL_HAS_SUBNORM

非推奨・削除の詳細

C言語側で対応するマクロ*_HAS_SUBNORMが廃止されたため、C++側でも非推奨とする。

この機能はコンパイル時定数として非正規化数のサポート状況を取得するものであった。しかし、これには以下のような問題があった:

  • ハードウェアによっては非正規化数をサポートしていない場合があり、その場合はソフトウェアエミュレーションによってサポートされている場合がある。この場合、同じ系統のハードウェアであっても将来のバージョンでサポートされる可能性があり、このときにABI破壊を回避しようとするとstd::denorm_indeterminateを常に使用せざるを得なくなってしまう
  • ハードウェアサポートがある場合でも、実行時のフラグ切り替えによって非正規化数をゼロにフラッシュするように設定することが可能であり、非正規化数のサポート状況は必ずしもコンパイル時に確定するプロパティではない場合がある

これらの理由から、この機能は有用なものではなく、最悪勘違いして使用される危険性があるため、非推奨とする。

#include <iostream>
#include <limits>
#include <stdexcept>
#include <string>

std::string denorm_string(std::float_denorm_style e)
{
  switch (e) {
    case std::denorm_indeterminate: return "indeterminate";
    case std::denorm_absent:        return "absent";
    case std::denorm_present:       return "present";
  }
  throw std::invalid_argument("not support value");
}

int main()
{
  constexpr std::float_denorm_style a = std::numeric_limits<int>::has_denorm;
  constexpr std::float_denorm_style b = std::numeric_limits<float>::has_denorm;
  constexpr std::float_denorm_style c = std::numeric_limits<double>::has_denorm;

  std::cout << std::boolalpha;
  std::cout << "int : " << denorm_string(a) << std::endl;
  std::cout << "float : " << denorm_string(b) << std::endl;
  std::cout << "double : " << denorm_string(c) << std::endl;
}

出力例

int : absent
float : present
double : present

参照