# Function gcd

## Synopsis

``````#include "breeze/mathematics/gcd.hpp"

template <typename T>
constexpr T gcd(T a, T b)
``````

## Description

Returns the greatest common divisor of two integers.

If `T` is not an integral type the program is ill-formed. If the greatest common divisor of `|a|` and `|b|` is not representable as a value of type `T`, the behavior is undefined.

Returns
If both `a` and `b` are zero, returns zero. Otherwise it returns the greatest common divisor of `|a|` and `|b|`.
Note
The intent, for both this template and `breeze::lcm()`, was to follow the standard specification (the initial Breeze versions followed the C++ Library Fundamental TS v2, and I meant to update them to C++17 when C++17 would be out). But I soon realized that allowing two different types for the two arguments, and using `common_type` for the result, made everything very hard to reason about (can you tell what the `common_type` of two arbitrary integral types is?). So I decided to stick to what I consider a saner specification.
See
lcm().

## Source

Lines 15-40 in breeze/mathematics/brz/gcd.tpp. Line 48 in breeze/mathematics/gcd.hpp.

``````template< typename T >
constexpr T
gcd( T a, T b )
{
static_assert( std::is_integral< T >::value, "T must be integral" ) ;
using gcd_lcm_private::absolute_value ;
using mathematics_private::would_division_overflow ;

if ( would_division_overflow( b, a ) ||
would_division_overflow( a, b ) ) {
return 1 ;
}

while ( true ) {

if ( a == 0 ) {
return absolute_value( b ) ;
}
b %= a ;

if ( b == 0 ) {
return absolute_value( a ) ;
}
a %= b ;
}
}
``````