- limits[meta header]
- std[meta namespace]
- numeric_limits[meta class]
- variable[meta id-type]
// C++03
static const bool is_modulo;
// C++11
static constexpr bool is_modulo;
加算 (+
) ・減算 (-
) ・乗算 (*
) における数学的な値と、その型での値との間に (max() - min() + 1
) を法として常に合同関係があるかを判定する。
この性質を持つ型は、オーバーフロー時に最大値+1で剰余した値となる。
符号なし整数型の場合は常にtrue
となる。
- C++03 : 多くのマシンでは、浮動小数点数型の場合は
false
に、符号付き整数型の場合はtrue
になる - C++17 : 標準では符号付き整数型は
false
となる。標準の拡張として実装の符号あり整数型が、未定義動作としてではなく正しくオーバーフローする場合、true
と定義される
- C++03の「ほとんどのマシンでは符号付き整数型は
true
になる」という仕様は、符号あり整数型の未定義動作としてのオーバーフロー動作を正しいものとして扱ってしまっていた。これは間違いであった。C++17では、符号あり整数型は標準ではfalse
とし、実装がオーバーフロー時に値を折り返す場合にtrue
と定義されるように修正された - コンパイルオプション
- GCCとClangでは、
-fwrapv
オプションをつけることで、符号付き整数型を2の補数表現として折り返すよう動作を規定するが、is_modulo
はfalse
となる - Visual C++では、
d2UndefIntOverflow
オプションをつけることで、符号付き整数型のオーバーフローを利用するコードの最適化を無効化し、値を折り返す動作になるが、is_modulo
はfalse
となる
- GCCとClangでは、
#include <iostream>
#include <cassert>
#include <limits>
int main()
{
std::cout << std::boolalpha;
std::cout << "int : " << std::numeric_limits<int>::is_modulo << std::endl;
std::cout << "unsigned int : " << std::numeric_limits<unsigned int>::is_modulo << std::endl;
std::cout << "float : " << std::numeric_limits<float>::is_modulo << std::endl;
std::cout << "char : " << std::numeric_limits<char>::is_modulo << std::endl;
std::cout << "char : " << std::numeric_limits<bool>::is_modulo << std::endl;
assert(std::numeric_limits<unsigned int>::max() + 1 == 0u);
}
- is_modulo[color ff0000]
- max()[link max.md]
int : false
unsigned int : true
float : false
char : false
char : false