### 2837. `gcd` and `lcm` should support a wider range of input values

**Section:** 29.8.13 [numeric.ops.gcd], 29.8.14 [numeric.ops.lcm] **Status:** C++17
**Submitter:** Marshall Clow **Opened:** 2016-12-16 **Last modified:** 2017-07-30

**Priority: **0

**View all other** issues in [numeric.ops.gcd].

**View all issues with** C++17 status.

**Discussion:**

This is a duplicate of 2792, which addressed LFTS 2.

By the current definition, `gcd((int64_t)1234, (int32_t)-2147483648)` is
ill-formed (because `2147483648` is not representable as a value of `int32_t`.)
We want to change this case to be well-formed. As long as both `|m|` and `|n|`
are representable as values of the common type, absolute values can
be calculate `d` without causing unspecified behavior, by converting `m` and `n`
to the common type before taking the negation.

Suggested resolution:

`|m|` shall be representable as a value of type `M` and `|n|` shall
be representable as a value of type `N``|m|` and `|n|` shall be
representable as a value of `common_type_t<M, N>`.

*[2017-01-27 Telecon]*

Priority 0

**Proposed resolution:**

This wording is relative to N4604.

Edit 29.8.13 [numeric.ops.gcd] as indicated:

template<class M, class N>
constexpr common_type_t<M, N> gcd(M m, N n);

-2- *Requires:* `|m|` shall be representable as a value of type `M` and `|n|` shall
be representable as a value of type `N``|m|` and `|n|` shall be representable as
a value of `common_type_t<M, N>`. [*Note:* These requirements ensure, for example, that
`gcd(m, m) = |m|` is representable as a value of type `M`. — *end note*]

Edit 29.8.14 [numeric.ops.lcm] as indicated:

template<class M, class N>
constexpr common_type_t<M, N> lcm(M m, N n);

-2- *Requires:* `|m|` shall be representable as a value of type `M` and `|n|` shall
be representable as a value of type `N``|m|` and `|n|` shall be representable as
a value of `common_type_t<M, N>`. The least common multiple of `|m|` and `|n|` shall
be representable as a value of type `common_type_t<M, N>`.