C++ 参考手册

static const bool tinyness_before;
(C++11 前)
static constexpr bool tinyness_before;
(C++11 起)

std::numeric_limits<T>::tinyness_before 的值对所有测试浮点表达式在舍入前下溢的浮点类型 Ttrue

标准特化

 
T std::numeric_limits<T>::tinyness_before 的值
/* non-specialized */ false
bool false
char false
signed char false
unsigned char false
wchar_t false
char8_t false
char16_t false
char32_t false
short false
unsigned short false
int false
unsigned int false
long false
unsigned long false
long long false
unsigned long long false
float 实现定义
double 实现定义
long double 实现定义

注意

符合标准的 IEEE 754 浮点实现要求检测浮点下溢,并在执行处有二种可选的情形

1) 若假如以指数范围和精度均为无界的计算,产生绝对值小于 std::numeric_limits<T>::min() 的结果,则发生下溢(并且可能引发 FE_UNDERFLOW )。这种实现在舍入前检测是否较小(如 UltraSparc 、 POWER )。
2) 若舍入到目标浮点类型(即舍入到 std::numeric_limits<T>::digits 位)后,结果的绝对值小于 std::numeric_limits<T>::min() ,则发生下溢(并且可能引发 FE_UNDERFLOW )。正式地说,假如以指数范围和精度均为无界的计算,非零结果的绝对值小于 std::numeric_limits<T>::min() 。这种实现在舍入后检测是否较小(如 SuperSparc )

示例

最大非正规数乘 1.0 加上一个机器 epsilon 在舍入前给出小值 0x0.fffffffffffff8p-1022 ,而非舍入后的正规值 1p-1022 。用于执行此测试的实现( IBM Power7 )检测摄入前是否较小。

#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; // 仅若 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

参阅

鉴别浮点类型是否检测精度损失为非正规损失,而非不准确结果
(公开静态成员常量)
[静态]
鉴别浮点类型所用的非正规风格
(公开静态成员常量)