std::numeric_limits<T>::tinyness_before
From cppreference.com
static const bool tinyness_before; |
(C++11まで) | |
| static constexpr bool tinyness_before; |
(C++11以降) | |
浮動小数点型のすべての `T` について、`std::numeric_limits<T>::tinyness_before` の値は `true` です。これは、丸め処理の前に浮動小数点式のテスト結果がアンダーフローを検出する型です。
目次 |
[編集] 標準特殊化
T
|
`std::numeric_limits<T>::tinyness_before` の値 |
| /* 非特殊化 */ | false |
| bool | false |
| char | false |
| signed char | false |
| unsigned char | false |
| wchar_t | false |
| char8_t (C++20 以降) | false |
| char16_t (C++11 以降) | false |
| char32_t (C++11 以降) | false |
| short | false |
| unsigned short | false |
| int | false |
| unsigned int | false |
| long | false |
| unsigned long | false |
| long long (C++11 以降) | false |
| unsigned long long (C++11 以降) | false |
| float | 実装定義 |
| double | 実装定義 |
| long double | 実装定義 |
[編集] 注釈
標準に準拠した IEEE 754 浮動小数点実装では、浮動小数点アンダーフローを検出することが要求されており、この検出には 2 つの代替的な状況があります。
- 計算結果の絶対値が、指数範囲と精度が無限であるかのように計算された場合に、`std::numeric_limits<T>::min()` よりも小さい場合、アンダーフローが発生します(そして `FE_UNDERFLOW` が発生する可能性があります)。このような実装は、丸め処理の前にタイジネス(underflow)を検出します(例: UltraSparc, POWER)。
- 結果をターゲットの浮動小数点型に丸めた後(つまり、`std::numeric_limits<T>::digits` ビットに丸めた後)、結果の絶対値が `std::numeric_limits<T>::min()` よりも小さい場合、アンダーフローが発生します(そして `FE_UNDERFLOW` が発生する可能性があります)。形式的には、非ゼロの結果の絶対値(指数範囲が無限であるかのように計算されたもの)は `std::numeric_limits<T>::min()` よりも小さいです。このような実装は、丸め処理の後にタイジネス(underflow)を検出します(例: SuperSparc)。
[編集] 例
最大の非正規数に、1.0 より 1 マシン epsilon 大きい数を乗算すると、丸め処理前には 0x0.fffffffffffff8p-1022 という非常に小さい値になりますが、丸め処理後には正規化された値 1p-1022 になります。このテストを実行するために使用された実装(IBM Power7)は、丸め処理の前にタイジネス(underflow)を検出します。
このコードを実行
#include <iostream> #include <limits> #include <cmath> #include <cfenv> int main() { std::cout << "Tinyness before: " << std::boolalpha << std::numeric_limits<double>::tinyness_before << '\n'; double denorm_max = std::nextafter(std::numeric_limits<double>::min(), 0); double multiplier = 1 + std::numeric_limits<double>::epsilon(); std::feclearexcept(FE_ALL_EXCEPT); double result = denorm_max * multiplier; // Underflow only if tinyness_before if (std::fetestexcept(FE_UNDERFLOW)) std::cout << "Underflow detected\n"; std::cout << std::hexfloat << denorm_max << " x " << multiplier << " = " << result << '\n'; }
実行結果の例
Tinyness before: true Underflow detected 0xf.ffffffffffffp-1030 x 0x1.0000000000001p+0 = 0x1p-1022
[編集] 関連項目
| [static] |
精度の損失を不正確な結果ではなく非正規化損失として検出する浮動小数点数型を識別する (public static member constant) |
| [static] |
浮動小数点数型で使用される非正規化のスタイルを識別する (public static member constant) |