Hypot
定义于头文件 <cmath>
中。
描述
声明 1-3 (C++23)
计算 `x` 和 `y` 的平方和的平方根,在计算的中间阶段没有不适当的溢出或下溢。库为所有 cv-unqualified 浮点类型作为参数 `x` 和 `y` 的类型提供 `std::hypot` 的重载。
声明 4 (C++23)
计算 `x`、`y` 和 `z` 的平方和的平方根,在计算的中间阶段没有不适当的溢出或下溢。库为所有 cv-unqualified 浮点类型作为参数 `x`、`y` 和 `z` 的类型提供 `std::hypot` 的重载。
此函数的双参数版本计算的值是直角三角形斜边的长度,其边长为 `x` 和 `y`,或者是点 `(x,y)` 到原点 `(0,0)` 的距离,或者是复数 `x+iy` 的模。
此函数的三参数版本计算的值是长方体的体对角线长度,其边长为 `x`、`y` 和 `z`,或者是点 `(x,y,z)` 到原点 `(0,0,0)` 的距离。
声明
- C++23
- C++17
- C++11
// 1)
/* floating-point-type */ hypot( /* floating-point-type */ x,
/* floating-point-type */ y );
// 2)
float hypotf( float x, float y );
// 3)
long double hypotl( long double x, long double y );
// 4)
/* floating-point-type */ hypot( /* floating-point-type */ x,
/* floating-point-type */ y,
/* floating-point-type */ z );
// 5)
template< class Arithmetic1, Arithmetic2 >
/* common-floating-point-type */ hypot( Arithmetic1 x, Arithmetic2 y );
// 6)
template< class Arithmetic1, Arithmetic2, Arithmetic3 >
/* common-floating-point-type */
hypot( Arithmetic1 x, Arithmetic2 y, Arithmetic3 z );
// 1)
float hypot ( float x, float y );
// 2)
double hypot ( double x, double y );
// 3)
long double hypot ( long double x, long double y );
// 4)
float hypotf( float x, float y );
// 5)
long double hypotl( long double x, long double y );
// 6)
float hypot ( float x, float y, float z );
// 7)
double hypot ( double x, double y, double z );
// 8)
long double hypot ( long double x, long double y, long double z );
// 9)
template< class Arithmetic1, Arithmetic2 >
/* common-floating-point-type */ hypot( Arithmetic1 x, Arithmetic2 y );
// 10)
template< class Arithmetic1, Arithmetic2, Arithmetic3 >
/* common-floating-point-type */
hypot( Arithmetic1 x, Arithmetic2 y, Arithmetic3 z );
// 1)
float hypot ( float x, float y );
// 2)
double hypot ( double x, double y );
// 3)
long double hypot ( long double x, long double y );
// 4)
float hypotf( float x, float y );
// 5)
long double hypotl( long double x, long double y );
// 6)
template< class Arithmetic1, Arithmetic2 >
/* common-floating-point-type */ hypot( Arithmetic1 x, Arithmetic2 y );
参数
`x`, `y`, `z` - 浮点或整数值
返回值
1-3,A) 如果没有错误发生,则返回直角三角形的斜边 (√(x2+y2))。
4,B) 如果没有错误发生,则返回 3D 空间中到原点的距离 (√(x2+y2+z2))。
如果因溢出导致范围错误,则返回 +HUGE_VAL
、+HUGE_VALF
或 +HUGE_VALL
。
如果因下溢导致范围错误,则返回正确的结果(四舍五入后)。
错误处理
错误按照math_errhandling中的规定报告
如果实现支持 IEEE 浮点运算(IEC 60559),
`std::hypot(x, y)`、`std::hypot(y, x)` 和 `std::hypot(x, -y)` 是等效的
如果其中一个参数是 `±0`,则 `std::hypot(x, y)` 等效于使用非零参数调用的 std::fabs
如果其中一个参数是 `±∞`,则 `std::hypot(x, y)` 返回 `+∞`,即使另一个参数是 NaN
否则,如果任何参数是 NaN,则返回 NaN
备注
实现通常保证精度小于 1 ulp(最小精度单位):GNU,BSD。
`std::hypot(x, y)` 等效于 `std::abs(std::complex<double>(x, y))`。
POSIX 规定只有当两个参数都是非规范化数且正确结果也是非规范化数时,才可能发生下溢(这禁止了简单的实现)。
三维空间中两点 `(x1,y1,z1)` 和 `(x2,y2,z2)` 之间的距离可以使用 std::hypot 的三参数重载计算:`std::hypot(x2 - x1, y2 - y1, z2 - z1)`。 (自 C++17 起)
不需要严格按照附加重载提供额外的重载。它们只需要足以确保对于它们的第一个参数`num1`、第二个参数`num2`和可选的第三个参数`num3`:
如果 `num1`、`num2` 或 `num3` 的类型是 long double,那么
`std::hypot(num1, num2)` 的效果与
`std::hypot(static_cast<long double>(num1), static_cast<long double>(num2))` 相同。
并且 `std::hypot(num1, num2, num3)` 的效果与
`std::hypot(static_cast<long double>(num1), static_cast<long double>(num2), static_cast<long double>(num3))` 相同。
否则,如果 `num1`、`num2` 和/或 `num3` 的类型是 double 或整数类型,则
`std::hypot(num1, num2)` 的效果与
`std::hypot(static_cast<double>(num1), static_cast<double>(num2))`。
并且 `std::hypot(num1, num2, num3)` 的效果与
`std::hypot(static_cast<double>(num1), static_cast<double>(num2), static_cast<double>(num3))`。
否则,如果 `num1`、`num2` 或 `num3` 的类型是 float,则
`std::hypot(num1, num2)` 的效果与
`std::hypot(static_cast<float>(num1), static_cast<float>(num2))`。
并且 `std::hypot(num1, num2, num3)` 的效果与
`std::hypot(static_cast<float>(num1), static_cast<float>(num2), static_cast<float>(num3))` 相同。 (直到 C++23)
如果 `num1`、`num2` 和 `num3` 具有算术类型,则
`std::hypot(num1, num2)` 的效果与
std::hypot(static_cast</* common-floating-point-type */>(num1), static_cast</* common-floating-point-type */>(num2))
.
并且 `std::hypot(num1, num2, num3)` 的效果与
std::hypot(static_cast</* common-floating-point-type */>(num1), static_cast</* common-floating-point-type */>(num2), static_cast</* common-floating-point-type */>(num3))
其中 /* common-floating-point-type */ 是在 `num1`、`num2` 和 `num3` 的类型中,具有最高浮点转换等级和最高浮点转换次等级的浮点类型;整数类型的参数被认为具有与 double 相同的浮点转换等级。
如果不存在具有最高等级和子等级的浮点类型,则重载决议不会从提供的重载中产生可用的候选。
示例
#include <cerrno>
#include <cfenv>
#include <cfloat>
#include <cmath>
#include <cstring>
#include <iostream>
// #pragma STDC FENV_ACCESS ON
struct Point3D { float x, y, z; };
int main()
{
// typical usage
std::cout
<< "(1,1) cartesian is ("
<< std::hypot(1,1)
<< ',' << std::atan2(1,1)
<< ") polar\n";
Point3D a{3.14, 2.71, 9.87}, b{1.14, 5.71, 3.87};
// C++17 has 3-argument hypot overload:
std::cout
<< "distance(a,b) = "
<< std::hypot(a.x - b.x, a.y - b.y, a.z - b.z)
<< '\n';
// special values
std::cout
<< "hypot(NAN,INFINITY) = "
<< std::hypot(NAN, INFINITY) << '\n';
// error handling
errno = 0;
std::feclearexcept(FE_ALL_EXCEPT);
std::cout
<< "hypot(DBL_MAX,DBL_MAX) = "
<< std::hypot(DBL_MAX, DBL_MAX) << '\n';
if (errno == ERANGE)
std::cout
<< "errno = ERANGE "
<< std::strerror(errno) << '\n';
if (std::fetestexcept(FE_OVERFLOW))
std::cout
<< "FE_OVERFLOW raised\n";
}
(1,1) cartesian is (1.41421,0.785398) polar
distance(a,b) = 7
hypot(NAN,INFINITY) = inf
hypot(DBL_MAX,DBL_MAX) = inf
errno = ERANGE Numerical result out of range
FE_OVERFLOW raised