- numeric[meta header]
- function template[meta id-type]
- std[meta namespace]
- cpp17[meta cpp]
- [mathjax enable]
namespace std {
template <class M, class N>
constexpr common_type_t<M, N> gcd(M m, N n);
}
- common_type_t[link /reference/type_traits/common_type.md]
最大公約数 (greatest common divisor, gcd) を求める。
- 型
M
およびN
がbool
以外の整数型であること
この要件を満たさない場合、プログラムは不適格となる |m|
および|n|
がcommon_type_t
<M, N>
の値として表現できること
この要件を満たさない場合の動作は未定義
m
およびn
が 0 の場合 0 を返す- それ以外の場合引数
|m|
と|n|
の最大公約数を返す
投げない。
#include <iostream>
#include <limits>
#include <numeric>
#include <type_traits>
int main() {
static_assert(std::gcd(0, 0) == 0);
static_assert(std::gcd(3u, -7l) == 1);
// 符号付き整数の場合戻り値が負になることがある
using T = int32_t;
constexpr auto m = std::numeric_limits<T>::min();
const auto gs = std::gcd<T, T>(m, m); // -m が int32_t で表せないと m < 0 になる
std::cout << "gcd<int32_t, int32_t>(" << m << ", " << m << ") " << gs << std::endl;
// 符号なし整数にすれば戻り値は正
using U = std::make_unsigned<T>::type; // uint32_t
const auto gu = std::gcd<U, U>(m, m);
std::cout << "gcd<uint32_t, uint32_t>(" << m << ", " << m << ") " << gu << std::endl;
}
- std::gcd[color ff0000]
- min[link /reference/limits/numeric_limits/min.md]
- std::make_unsigned[link /reference/type_traits/make_unsigned.md]
gcd<int32_t, int32_t>(-2147483648, -2147483648) -2147483648
gcd<uint32_t, uint32_t>(-2147483648, -2147483648) 2147483648
- C++17
- Clang: 4.0.0
- GCC: 7.1.0
- ICC: ??
- Visual C++: ??
要件 2 を満たすかどうかチェックしないが、戻り値を constexpr
指定するとオーバーフロー時にコンパイルエラーとなることがある。
要件 2 を満たさない場合、オーバーフローにより戻り値が負になることがある。
要件 2 を満たすかどうかチェックしないが、戻り値を constexpr
指定するとオーバーフロー時にコンパイルエラーとなることがある。
要件 2 を満たさない場合、オーバーフローにより戻り値が負になることがある。
- WG21 N3845 Greatest Common Divisor and Least Common Multiple
- WG21 N3913 Greatest Common Divisor and Least Common Multiple, v2
- WG21 N4061 Greatest Common Divisor and Least Common Multiple, v3
- WG21 P0295R0 Adopt Selected Library Fundamentals V2 Components for C++17
- LWG Issue 2837.
gcd
andlcm
should support a wider range of input values - LWG Issue 2759.
gcd
/lcm
andbool
for the WP