std::numeric_limits<T>::is_modulo
来自cppreference.com
< cpp | types | numeric limits
static const bool is_modulo; |
(C++11 前) | |
static constexpr bool is_modulo; |
(C++11 起) | |
std::numeric_limits<T>::is_modulo 对所有可能 (C++11 前)以模算术处理溢出的算术类型 T
为 true 。模算术即若此类型的加法、减法、乘法或除法结果会落在范围 [min(), max()] 外,则这种运算返回的结果与期望值相差 max()-min()+1 的整数倍。
|
(C++11 起) |
标准特化
T
|
std::numeric_limits<T>::is_modulo 的值 |
/* non-specialized */ | false |
bool | false |
char | 实现定义 |
signed char | 实现定义 |
unsigned char | true |
wchar_t | 实现定义 |
char8_t | true |
char16_t | true |
char32_t | true |
short | 实现定义 |
unsigned short | true |
int | 实现定义 |
unsigned int | true |
long | 实现定义 |
unsigned long | true |
long long | 实现定义 |
unsigned long long | true |
float | false |
double | false |
long double | false |
注意
尽管 C++11 标准仍然说“在大多数机器上,这对于有符号整数为 true
”,这是缺陷而且已被更正。准确措辞从 C++03 到 C++11 的更改使得 true 值不再与有符号整数溢出上的未定义行为兼容。因此,依赖于有符号溢出为未定义(为了优化机会)的实现现在对有符号整数设置 is_modulo
为 false
。见示例 GCC PR 22200 。
示例
演示模类型的行为
运行此代码
#include <iostream> #include <type_traits> #include <limits> template<class T> typename std::enable_if<std::numeric_limits<T>::is_modulo>::type check_overflow() { std::cout << "\nmax value is " << std::numeric_limits<T>::max() << '\n' << "min value is " << std::numeric_limits<T>::min() << '\n' << "max value + 1 is " << std::numeric_limits<T>::max()+1 << '\n'; } int main() { check_overflow<int>(); check_overflow<unsigned long>(); // check_overflow<float>(); // 编译时错误,非模类型 }
可能的输出:
max value is 2147483647 min value is -2147483648 max value + 1 is -2147483648 max value is 18446744073709551615 min value is 0 max value + 1 is 0
缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。
DR | 应用于 | 出版时的行为 | 正确行为 |
---|---|---|---|
LWG 2422 | C++11 | 曾在大多数机器上要求 is_modulo 对有符号整数类型为 true
|
对有符号整数类型要求为 false , 除非定义有符号整数溢出为回绕 |
参阅
[静态] |
鉴别整数类型 (公开静态成员常量) |
[静态] |
鉴别 IEC 559/IEEE 754 浮点类型 (公开静态成员常量) |
[静态] |
鉴别准确表示的类型 (公开静态成员常量) |