<p>I've checked the <a href="https://en.cppreference.com/w/cpp/numeric/math/hypot" rel="nofollow noreferrer">information on cppreference.com</a> and found that there are only 2 and 3 input <code>hypot</code> function. I am wondering why not implement the variadic version of <code>hypot</code> function in standard library as below.</p>
<pre><code>//  hypot Template Function Implementation
template&lt;typename... Args&gt;
auto hypot(Args... args)
{
    return std::sqrt((std::pow(args, 2.0) + ...));
}
</code></pre>

<c++><standard-library><math>
Is there any particular reason to only implement 2 and 3 input hypot?
CC BY-SA 4.0
2024-12-25T16:51:15.267Z
The naïve algorithm runs the risk of overflow/underflow. In the documentation, it mentions that the 2-argument and 3-argument versions are designed to resist undue over-/underflow, so it would probably be significantly more difficult/slower to implement a variadic version with this behaviour.
Someone
CC BY-SA 4.0
2024-12-25T20:05:39.803Z
Because 2 and 3 argument versions are used vastly more often.
CPlus
CC BY-SA 4.0
2024-12-29T01:58:14.920Z
As I often pointed out when asked why a one-line method was not in the .NET BCL -- it's hardly worth the effort to spec, implement, test, document and maintain forever a method that the user can write in a minute when they need it!
Eric Lippert
CC BY-SA 4.0
2024-12-29T01:59:19.177Z
More generally, a "why not" question presupposes that there must be a good reason to NOT do work for someone else to use. But that's not how life goes. You've got to provide a good reason for other people to do work for you!
Eric Lippert
CC BY-SA 4.0
2024-12-29T08:09:41.293Z
@EricLippert: The one line implementation of `hypot` is no good, since the whole point of the function is to give precise results in cases where the trivial implementation would suffer overflow or loss of precision in intermediate steps. Writing a good version of `hypot` even for two inputs is not straightforward, let alone n inputs.
Nate Eldredge
CC BY-SA 4.0
2024-12-29T08:13:40.403Z
For instance, openbsd's implementation is about 80 lines: https://github.com/openbsd/src/blob/master/lib/libm/src/e_hypot.c
Nate Eldredge
CC BY-SA 4.0
2024-12-29T19:30:09.670Z
Thanks, I misunderstood the thrust of your question, which as I now understand it is actually to code review the proposed implementation.
Eric Lippert
CC BY-SA 4.0
2024-12-30T05:09:53.053Z
For what it's worth, another, rather different, sort of implementation of `hypot` that avoids most overflow, underflow, etc. https://stackoverflow.com/a/3506633/179910
Jerry Coffin
<p>The <a href="https://www.open-std.org/JTC1/SC22/WG21/docs/papers/2015/p0030r1.pdf" rel="nofollow noreferrer">Proposal to Introduce a 3-Argument Overload to std::hypot</a> gave the following justification:</p>
<blockquote>
<p>We considered proposing a variadic overload of <code>std::hypot</code>, so that it could be further
generalized to compute the Euclidean norm of a vector of arbitrary dimension. However, the
general utility of such a feature is not immediately clear; we judge it best (at least for now) to
relegate such a feature to domain-specific libraries, like the GNU Scientific Library [GSL].</p>
</blockquote>
<p>They further justified the need for a three-argument hypothenuse:</p>
<blockquote>
<p>The <code>std::hypot</code> function, adopted for C++11 via [N1836] and later [N2009], has proven to be a
useful general math utility function. One major application of this function is the calculation of
the distance between 2 points in a 2-dimensional space. However, this is not useful enough, as
many scientific and engineering applications (e.g. n-body simulations) model points in 3-
dimensional space. [...] Using only the current definition of <code>std::hypot</code>, the distance between 2 points in a 3-
dimensional space can at best be calculated as such:</p>
<p><code>auto d = std::hypot(x2-x1, std::hypot(y2-y1, z2-z1));</code></p>
<p>This code is far from optimal because it involves 2 function calls to <code>std::hypot</code> as well as an
extra square-root and power operation.</p>
</blockquote>
<p>The obvious implementation of the variadic hypothenuse iterates the two-argument hypothenuse, collapsing two numbers into one with each iteration. My implementation is included below. For three arguments, it is equivalent to the solution the authors described as &quot;far from optimal&quot; in their proposal.</p>
<pre><code>namespace std
{
    template&lt;typename Arg1, typename Arg2, typename... Args&gt;
    auto hypot(Arg1 arg1, Arg2 arg2, Args... args)
    {
        return hypot(hypot(arg1, arg2), args...);
    }
}
</code></pre>
<p>Your implementation with <code>std::pow</code> and <code>std::sqrt</code> is inaccurate and prone to overflow.</p>
<hr />
<p>In summary:</p>
<ul>
<li>There is a strong need for a good two-argument and three-argument hypothenuse.</li>
<li>The obvious variadic implemenations are either slow or inaccurate, so special cases for two and three arguments are needed anyway.</li>
<li>There is little need for a hypothenuse with four or more arguments.</li>
<li>There is need for a vector norm (begin + end iterators, C++20 ranges) but that's a different beast.</li>
</ul>

CC BY-SA 4.0
2024-12-25T20:28:22.323Z
2024-12-25T20:36:55.070Z
2024-12-25T20:36:55.070Z
Rainer P.
# Is there any particular reason to only implement 2 and 3 input hypot?
Posted by: username_0 on 2024-12-25
I've checked the information on cppreference.com and found that there are only 2 and 3 input hypot function. I am wondering why not implement the variadic version of hypot function in standard library as below.
//  hypot Template Function Implementation
template
auto hypot(Args... args)
{
    return std::sqrt((std::pow(args, 2.0) + ...));
}
**Tags:** c++ standard-library math
> **Comments:**
> **username_1**: The naïve algorithm runs the risk of overflow/underflow. In the documentation, it mentions that the 2-argument and 3-argument versions are designed to resist undue over-/underflow, so it would probably be significantly more difficult/slower to implement a variadic version with this behaviour.  
> **username_2**: Because 2 and 3 argument versions are used vastly more often.  
> **username_3**: As I often pointed out when asked why a one-line method was not in the .NET BCL -- it's hardly worth the effort to spec, implement, test, document and maintain forever a method that the user can write in a minute when they need it!  
> **username_3**: More generally, a "why not" question presupposes that there must be a good reason to NOT do work for someone else to use. But that's not how life goes. You've got to provide a good reason for other people to do work for you!  
> **username_4**: @EricLippert: The one line implementation of `hypot` is no good, since the whole point of the function is to give precise results in cases where the trivial implementation would suffer overflow or loss of precision in intermediate steps. Writing a good version of `hypot` even for two inputs is not straightforward, let alone n inputs.  
> **username_4**: For instance, openbsd's implementation is about 80 lines: https://github.com/openbsd/src/blob/master/lib/libm/src/e_hypot.c  
> **username_3**: Thanks, I misunderstood the thrust of your question, which as I now understand it is actually to code review the proposed implementation.  
> **username_5**: For what it's worth, another, rather different, sort of implementation of `hypot` that avoids most overflow, underflow, etc. https://stackoverflow.com/a/3506633/179910  
---
## 1 answers
### Answer by username_6 on 2024-12-25. Score: 2 | Accepted answer
The Proposal to Introduce a 3-Argument Overload to std::hypot gave the following justification:

We considered proposing a variadic overload of std::hypot, so that it could be further
generalized to compute the Euclidean norm of a vector of arbitrary dimension. However, the
general utility of such a feature is not immediately clear; we judge it best (at least for now) to
relegate such a feature to domain-specific libraries, like the GNU Scientific Library [GSL].

They further justified the need for a three-argument hypothenuse:

The std::hypot function, adopted for C++11 via [N1836] and later [N2009], has proven to be a
useful general math utility function. One major application of this function is the calculation of
the distance between 2 points in a 2-dimensional space. However, this is not useful enough, as
many scientific and engineering applications (e.g. n-body simulations) model points in 3-
dimensional space. [...] Using only the current definition of std::hypot, the distance between 2 points in a 3-
dimensional space can at best be calculated as such:
auto d = std::hypot(x2-x1, std::hypot(y2-y1, z2-z1));
This code is far from optimal because it involves 2 function calls to std::hypot as well as an
extra square-root and power operation.

The obvious implementation of the variadic hypothenuse iterates the two-argument hypothenuse, collapsing two numbers into one with each iteration. My implementation is included below. For three arguments, it is equivalent to the solution the authors described as "far from optimal" in their proposal.
namespace std
{
    template
    auto hypot(Arg1 arg1, Arg2 arg2, Args... args)
    {
        return hypot(hypot(arg1, arg2), args...);
    }
}

Your implementation with std::pow and std::sqrt is inaccurate and prone to overflow.

In summary:

There is a strong need for a good two-argument and three-argument hypothenuse.
The obvious variadic implemenations are either slow or inaccurate, so special cases for two and three arguments are needed anyway.
There is little need for a hypothenuse with four or more arguments.
There is need for a vector norm (begin + end iterators, C++20 ranges) but that's a different beast.
---
