C ++标题<complex>
提供abs(z)
和norm(z)
。
复数z = x + iy的范数是norm(z)
:= x ^ 2 + y ^ 2.
z的绝对值为abs(z)
:= sqrt(norm(z))。
但是,以下示例显示abs(z)
必须以不同方式实现,因为尽管norm(z)
不会溢出,但它不会溢出。至少,它不会在g ++ 6.2.1下溢出。
标准是否保证这种非溢出?它是如何实现的?
#include <iostream>
#include <complex>
typedef std::complex<double> complex_t;
int main()
{
complex_t z = { 3e200, 4e200 };
double a = abs(z);
double n = norm(z);
std::cout << a << " -> " << std::isinf(a) << "\n";
std::cout << n << " -> " << std::isinf(n) << "\n";
return 0;
}
输出:
5e+200 -> 0
inf -> 1
答案 0 :(得分:2)
std::complex::abs
等同于std::hypot
函数,确实可以保证在计算的中间阶段避免溢出和下溢。
Wikipedia page on Hypot function提供了有关实施的一些见解。
我将引用伪代码以防万一:
// hypot for (x, y) != (0, 0)
double hypot(double x,double y)
{
double t;
x = abs(x);
y = abs(y);
t = min(x,y);
x = max(x,y);
t = t/x;
return x*sqrt(1+t*t);
}