std::numeric_limits<T>::is_modulo
来自cppreference.com
< cpp | types | numeric limits
staticconstbool is_modulo; | (C++11 前) | |
staticconstexprbool is_modulo; | (C++11 起) | |
std::numeric_limits<T>::is_modulo 对所有以模算术处理溢出的算术类型 T
都是 true。模算术即在此类型的加法、减法、乘法或除法结果会落在范围 [
min(),
max()]
外时,这种运算返回的结果会与期望值相差 max()- min()+1 的整数倍。
is_modulo
对有符号整数类型是 false,除非实现定义有符号整数溢出进行回绕。
目录 |
[编辑]标准特化
T | std::numeric_limits<T>::is_modulo 的值 |
/* 未特化 */ | false |
bool | false |
char | 由实现定义 |
signedchar | 由实现定义 |
unsignedchar | true |
wchar_t | 由实现定义 |
char8_t(C++20 起) | true |
char16_t(C++11 起) | true |
char32_t(C++11 起) | true |
short | 由实现定义 |
unsignedshort | true |
int | 由实现定义 |
unsignedint | true |
long | 由实现定义 |
unsignedlong | true |
longlong(C++11 起) | 由实现定义 |
unsignedlonglong(C++11 起) | true |
float | false |
double | false |
longdouble | false |
[编辑]注解
C++ 标准在修复 LWG 问题 2422 前记述“在大多数机器上,这对于有符号整数是 true
”。相关讨论参考 GCC PR 22200。
[编辑]示例
演示模运算类型的行为
运行此代码
#include <iostream>#include <type_traits>#include <limits> template<class T>typenamestd::enable_if<std::numeric_limits<T>::is_modulo>::type check_overflow(){std::cout<<"最大值是 "<<std::numeric_limits<T>::max()<<'\n'<<"最小值是 "<<std::numeric_limits<T>::min()<<'\n'<<"最大值 + 1 是 "<<std::numeric_limits<T>::max()+1<<'\n';} int main(){ check_overflow<int>();std::cout<<'\n'; check_overflow<unsignedlong>();// check_overflow<float>(); // 编译时错误,非模类型}
可能的输出:
最大值是 2147483647 最小值是 -2147483648 最大值 + 1 是 -2147483648 最大值是 18446744073709551615 最小值是 0 最大值 + 1 是 0
[编辑]缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。
缺陷报告 | 应用于 | 出版时的行为 | 正确行为 |
---|---|---|---|
LWG 612 | C++98 | “以模算术处理溢出”的定义很糟糕[1] | 提供更好的定义 |
LWG 2422 | C++11 | 曾在大多数机器上要求 is_modulo 对有符号整数类型是 true | 对有符号整数类型要求是 false, 除非定义有符号整数溢出为回绕 |
- ↑定义是“将两个正数相加的结果可以是回绕到的第三个更小的数”。这个定义有以下几个问题:
- 它没有定义回绕后的值。
- 它没有给出回绕是否会复现。
- 它没有定义对所有值的加、减和其他操作的行为
[编辑]参阅
[静态] | 鉴别整数类型 (公开静态成员常量) |
[静态] | 鉴别 IEC 559/IEEE 754 浮点数类型 (公开静态成员常量) |
[静态] | 鉴别准确表示的类型 (公开静态成员常量) |