数值极限
定义于头文件 <limits>
定义于头文件 | ||
template< class T > class numeric_limits; |
numeric_limits 类模板提供查询各种算术类型属性的标准化方式(例如 int 类型的最大可能值是 std::numeric_limits<int>::max() )。
鉴别类型所用的舍入模式
std::numeric_limits<T>::round_style
static const std::float_round_style round_style; | (C++11 前) | |
static constexpr std::float_round_style round_style; | (C++11 起) |
标准特化
T | std::numeric_limits<T>::round_style 的值 |
/* non-specialized */ | std::round_toward_zero |
bool | std::round_toward_zero |
char | std::round_toward_zero |
signed char | std::round_toward_zero |
unsigned char | std::round_toward_zero |
wchar_t | std::round_toward_zero |
char8_t | std::round_toward_zero |
char16_t | std::round_toward_zero |
char32_t | std::round_toward_zero |
short | std::round_toward_zero |
unsigned short | std::round_toward_zero |
int | std::round_toward_zero |
unsigned int | std::round_toward_zero |
long | std::round_toward_zero |
unsigned long | std::round_toward_zero |
long long | std::round_toward_zero |
unsigned long long | std::round_toward_zero |
float | 通常为 std::round_to_nearest |
double | 通常为 std::round_to_nearest |
long double | 通常为 std::round_to_nearest |
注意
这些值是常量,且不反映 std::fesetround 所做的舍入模式更改。被更改的值可从 FLT_ROUNDS 或 std::fegetround 获得。
示例
十进制值 0.1 不能表示成二进制浮点类型。在存储于 IEEE-745 double 时,它落入 0x1.9999999999999*2-4与 0x1.999999999999a*2-4之间。舍入到最近可表示结果导致 0x1.999999999999a*2-4。同样地,十进制值 0.3 在 0x1.3333333333333*2-2与 0x1.3333333333334*2-2
之间,舍入到最近值后存储为 0x1.3333333333333*2-2。
调用示例
#include <iostream>
#include <string>
#include <limits>
struct SName
{
};
//偏特化
struct SPartSpec
{
};
namespace std
{
template<>
struct numeric_limits<SPartSpec>
{
static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;
static _GLIBCXX_USE_CONSTEXPR bool is_signed = true;
static _GLIBCXX_USE_CONSTEXPR bool is_integer = true;
static _GLIBCXX_USE_CONSTEXPR bool is_exact = true;
static _GLIBCXX_USE_CONSTEXPR bool has_infinity = true;
static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = true;
static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = true;
static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm = denorm_present;
static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = true;
static _GLIBCXX_USE_CONSTEXPR float_round_style round_style = round_toward_neg_infinity;
};
}
int main()
{
std::cout << std::boolalpha;
std::cout << "std::numeric_limits<bool>::round_style: "
<< std::numeric_limits<bool>::round_style << std::endl;
std::cout << "std::numeric_limits<char>::round_style: "
<< std::numeric_limits<char>::round_style << std::endl;
std::cout << "std::numeric_limits<signed char>::round_style: "
<< std::numeric_limits<signed char>::round_style << std::endl;
std::cout << "std::numeric_limits<unsigned char>::round_style: "
<< std::numeric_limits<unsigned char>::round_style << std::endl;
std::cout << "std::numeric_limits<wchar_t>::round_style: "
<< std::numeric_limits<wchar_t>::round_style << std::endl;
std::cout << "std::numeric_limits<char16_t>::round_style: "
<< std::numeric_limits<char16_t>::round_style << std::endl;
std::cout << "std::numeric_limits<char32_t>::round_style: "
<< std::numeric_limits<char32_t>::round_style << std::endl;
std::cout << "std::numeric_limits<short>::round_style: "
<< std::numeric_limits<short>::round_style << std::endl;
std::cout << "std::numeric_limits<unsigned short>::round_style: "
<< std::numeric_limits<unsigned short>::round_style << std::endl;
std::cout << "std::numeric_limits<int>::round_style: "
<< std::numeric_limits<int>::round_style << std::endl;
std::cout << "std::numeric_limits<unsigned int>::round_style: "
<< std::numeric_limits<unsigned int>::round_style << std::endl;
std::cout << "std::numeric_limits<long>::round_style: "
<< std::numeric_limits<long>::round_style << std::endl;
std::cout << "std::numeric_limits<unsigned long>::round_style: "
<< std::numeric_limits<unsigned long>::round_style << std::endl;
std::cout << "std::numeric_limits<long long>::round_style: "
<< std::numeric_limits<long long>::round_style << std::endl;
std::cout << "std::numeric_limits<unsigned long long>::round_style: "
<< std::numeric_limits<unsigned long long>::round_style << std::endl;
std::cout << "std::numeric_limits<float>::round_style: "
<< std::numeric_limits<float>::round_style << std::endl;
std::cout << "std::numeric_limits<double>::round_style: "
<< std::numeric_limits<double>::round_style << std::endl;
std::cout << "std::numeric_limits<long double>::round_style: "
<< std::numeric_limits<long double>::round_style << std::endl;
std::cout << "std::numeric_limits<std::string>::round_style: "
<< std::numeric_limits<std::string>::round_style << std::endl;
std::cout << "std::numeric_limits<SName>::round_style: "
<< std::numeric_limits<SName>::round_style << std::endl;
std::cout << "std::numeric_limits<SPartSpec>::round_style: "
<< std::numeric_limits<SPartSpec>::round_style << std::endl;
return 0;
}
输出
鉴别 IEC 559/IEEE 754 浮点类型
std::numeric_limits<T>::is_iec559
static const bool is_iec559; | (C++11 前) | |
static constexpr bool is_iec559; | (C++11 起) |
std::numeric_limits<T>::is_iec559 的值对于所有符合 IEC 559 ( IEEE 754 )标准要求的浮点类型 T
为 true 。若 std::numeric_limits<T>::is_iec559 为 true ,则 std::numeric_limits<T>::has_infinity 、 std::numeric_limits<T>::has_quiet_NaN 与 std::numeric_limits<T>::has_signaling_NaN 亦为 true 。
标准特化
T | std::numeric_limits<T>::is_iec559 的值 |
/* 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 | 通常为 true |
double | 通常为 true |
long double | 通常为 true |
调用示例
#include <iostream>
#include <string>
#include <limits>
struct SName
{
};
//偏特化
struct SPartSpec
{
};
namespace std
{
template<>
struct numeric_limits<SPartSpec>
{
static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;
static _GLIBCXX_USE_CONSTEXPR bool is_signed = true;
static _GLIBCXX_USE_CONSTEXPR bool is_integer = true;
static _GLIBCXX_USE_CONSTEXPR bool is_exact = true;
static _GLIBCXX_USE_CONSTEXPR bool has_infinity = true;
static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = true;
static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = true;
static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm = denorm_present;
static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = true;
static _GLIBCXX_USE_CONSTEXPR float_round_style round_style = round_toward_neg_infinity;
static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = true;
};
}
int main()
{
std::cout << std::boolalpha;
std::cout << "std::numeric_limits<bool>::is_iec559: "
<< std::numeric_limits<bool>::is_iec559 << std::endl;
std::cout << "std::numeric_limits<char>::is_iec559: "
<< std::numeric_limits<char>::is_iec559 << std::endl;
std::cout << "std::numeric_limits<signed char>::is_iec559: "
<< std::numeric_limits<signed char>::is_iec559 << std::endl;
std::cout << "std::numeric_limits<unsigned char>::is_iec559: "
<< std::numeric_limits<unsigned char>::is_iec559 << std::endl;
std::cout << "std::numeric_limits<wchar_t>::is_iec559: "
<< std::numeric_limits<wchar_t>::is_iec559 << std::endl;
std::cout << "std::numeric_limits<char16_t>::is_iec559: "
<< std::numeric_limits<char16_t>::is_iec559 << std::endl;
std::cout << "std::numeric_limits<char32_t>::is_iec559: "
<< std::numeric_limits<char32_t>::is_iec559 << std::endl;
std::cout << "std::numeric_limits<short>::is_iec559: "
<< std::numeric_limits<short>::is_iec559 << std::endl;
std::cout << "std::numeric_limits<unsigned short>::is_iec559: "
<< std::numeric_limits<unsigned short>::is_iec559 << std::endl;
std::cout << "std::numeric_limits<int>::is_iec559: "
<< std::numeric_limits<int>::is_iec559 << std::endl;
std::cout << "std::numeric_limits<unsigned int>::is_iec559: "
<< std::numeric_limits<unsigned int>::is_iec559 << std::endl;
std::cout << "std::numeric_limits<long>::is_iec559: "
<< std::numeric_limits<long>::is_iec559 << std::endl;
std::cout << "std::numeric_limits<unsigned long>::is_iec559: "
<< std::numeric_limits<unsigned long>::is_iec559 << std::endl;
std::cout << "std::numeric_limits<long long>::is_iec559: "
<< std::numeric_limits<long long>::is_iec559 << std::endl;
std::cout << "std::numeric_limits<unsigned long long>::is_iec559: "
<< std::numeric_limits<unsigned long long>::is_iec559 << std::endl;
std::cout << "std::numeric_limits<float>::is_iec559: "
<< std::numeric_limits<float>::is_iec559 << std::endl;
std::cout << "std::numeric_limits<double>::is_iec559: "
<< std::numeric_limits<double>::is_iec559 << std::endl;
std::cout << "std::numeric_limits<long double>::is_iec559: "
<< std::numeric_limits<long double>::is_iec559 << std::endl;
std::cout << "std::numeric_limits<std::string>::is_iec559: "
<< std::numeric_limits<std::string>::is_iec559 << std::endl;
std::cout << "std::numeric_limits<SName>::is_iec559: "
<< std::numeric_limits<SName>::is_iec559 << std::endl;
std::cout << "std::numeric_limits<SPartSpec>::is_iec559: "
<< std::numeric_limits<SPartSpec>::is_iec559 << std::endl;
return 0;
}
输出
鉴别表示有限值集合的类型
std::numeric_limits<T>::is_bounded
static const bool is_bounded; | (C++11 前) | |
static constexpr bool is_bounded; | (C++11 起) |
std::numeric_limits<T>::is_bounded 对所有表示有限的值集合的算术类型 T
为 true 。所有基础类型均有界,不过此常量会在 std::numeric_limits 对库提供的任意精度算术类型的特化中为 false 。
标准特化
T | std::numeric_limits<T>::is_bounded 的值 |
/* non-specialized */ | false |
bool | true |
char | true |
signed char | true |
unsigned char | true |
wchar_t | true |
char8_t | true |
char16_t | true |
char32_t | true |
short | true |
unsigned short | true |
int | true |
unsigned int | true |
long | true |
unsigned long | true |
long long | true |
unsigned long long | true |
float | true |
double | true |
long double | true |
调用示例
#include <iostream>
#include <string>
#include <limits>
struct SName
{
};
//偏特化
struct SPartSpec
{
};
namespace std
{
template<>
struct numeric_limits<SPartSpec>
{
static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;
static _GLIBCXX_USE_CONSTEXPR bool is_signed = true;
static _GLIBCXX_USE_CONSTEXPR bool is_integer = true;
static _GLIBCXX_USE_CONSTEXPR bool is_exact = true;
static _GLIBCXX_USE_CONSTEXPR bool has_infinity = true;
static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = true;
static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = true;
static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm = denorm_present;
static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = true;
static _GLIBCXX_USE_CONSTEXPR float_round_style round_style = round_toward_neg_infinity;
static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = true;
static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
};
}
int main()
{
std::cout << std::boolalpha;
std::cout << "std::numeric_limits<bool>::is_bounded: "
<< std::numeric_limits<bool>::is_bounded << std::endl;
std::cout << "std::numeric_limits<char>::is_bounded: "
<< std::numeric_limits<char>::is_bounded << std::endl;
std::cout << "std::numeric_limits<signed char>::is_bounded: "
<< std::numeric_limits<signed char>::is_bounded << std::endl;
std::cout << "std::numeric_limits<unsigned char>::is_bounded: "
<< std::numeric_limits<unsigned char>::is_bounded << std::endl;
std::cout << "std::numeric_limits<wchar_t>::is_bounded: "
<< std::numeric_limits<wchar_t>::is_bounded << std::endl;
std::cout << "std::numeric_limits<char16_t>::is_bounded: "
<< std::numeric_limits<char16_t>::is_bounded << std::endl;
std::cout << "std::numeric_limits<char32_t>::is_bounded: "
<< std::numeric_limits<char32_t>::is_bounded << std::endl;
std::cout << "std::numeric_limits<short>::is_bounded: "
<< std::numeric_limits<short>::is_bounded << std::endl;
std::cout << "std::numeric_limits<unsigned short>::is_bounded: "
<< std::numeric_limits<unsigned short>::is_bounded << std::endl;
std::cout << "std::numeric_limits<int>::is_bounded: "
<< std::numeric_limits<int>::is_bounded << std::endl;
std::cout << "std::numeric_limits<unsigned int>::is_bounded: "
<< std::numeric_limits<unsigned int>::is_bounded << std::endl;
std::cout << "std::numeric_limits<long>::is_bounded: "
<< std::numeric_limits<long>::is_bounded << std::endl;
std::cout << "std::numeric_limits<unsigned long>::is_bounded: "
<< std::numeric_limits<unsigned long>::is_bounded << std::endl;
std::cout << "std::numeric_limits<long long>::is_bounded: "
<< std::numeric_limits<long long>::is_bounded << std::endl;
std::cout << "std::numeric_limits<unsigned long long>::is_bounded: "
<< std::numeric_limits<unsigned long long>::is_bounded << std::endl;
std::cout << "std::numeric_limits<float>::is_bounded: "
<< std::numeric_limits<float>::is_bounded << std::endl;
std::cout << "std::numeric_limits<double>::is_bounded: "
<< std::numeric_limits<double>::is_bounded << std::endl;
std::cout << "std::numeric_limits<long double>::is_bounded: "
<< std::numeric_limits<long double>::is_bounded << std::endl;
std::cout << "std::numeric_limits<std::string>::is_bounded: "
<< std::numeric_limits<std::string>::is_bounded << std::endl;
std::cout << "std::numeric_limits<SName>::is_bounded: "
<< std::numeric_limits<SName>::is_bounded << std::endl;
std::cout << "std::numeric_limits<SPartSpec>::is_bounded: "
<< std::numeric_limits<SPartSpec>::is_bounded << std::endl;
return 0;
}