C#Complex Tanh对于大值失败

时间:2018-11-20 13:30:14

标签: c# complex-numbers

这是Microsoft对Sinh的{​​{1}}的实现

Complex

以及public static Complex Sinh(Complex value) /* Hyperbolic sin */ { double a = value.m_real; double b = value.m_imaginary; return new Complex(Math.Sinh(a) * Math.Cos(b), Math.Cosh(a) * Math.Sin(b)); }

的实现
Cosh

最后是public static Complex Cos(Complex value) { double a = value.m_real; double b = value.m_imaginary; return new Complex(Math.Cos(a) * Math.Cosh(b), - (Math.Sin(a) * Math.Sinh(b))); }

的实现
Tanh

来源:https://referencesource.microsoft.com/System.Numerics/a.html#e62f37ac1d0c67da

我不明白为什么Microsoft以这种方式强行使用public static Complex Tanh(Complex value) /* Hyperbolic tan */ { return (Sinh(value) / Cosh(value)); } 方法?

对于很大的值,它将失败。例如:

  • Tanh,好的
  • tanh(709 + 0i) --> 1,失败应为1

有什么想法可以改进tanh(711 + 0i) --> NaN方法吗?

对于tanhdouble方法适用于较大的值。

2 个答案:

答案 0 :(得分:2)

复杂的tanh方法可以这样实现:

public static Complex Tanh(Complex value)
{
    double a = value.Real;
    double b = value.Imaginary;
    double tanh_a = Math.Tanh(a);
    double tan_b = Math.Tan(b);
    Complex num = new Complex(tanh_a, tan_b);
    Complex den = new Complex(1, tanh_a * tan_b);
    return num / den;
}

这对于较大的值同样适用,请参见https://dotnetfiddle.net/xGWdQt

更新

同样,复杂的tan方法也需要重新实现以适用于较大的值(虚部):

public static Complex Tan(Complex value)
{
    double a = value.Real;
    double b = value.Imaginary;
    double tan_a = Math.Tan(a);
    double tanh_b = Math.Tanh(b);
    Complex num = new Complex(tan_a, tanh_b);
    Complex den = new Complex(1, -tan_a * tanh_b);
    return num / den;
}

请参见https://dotnetfiddle.net/dh6CSG

答案 1 :(得分:0)

使用Hans Passant的评论来实现tanh方法的另一种方法是:

public static Complex Tanh(Complex value)
{
    if (Math.Abs(value.Real) > 20)
        return new Complex(Math.Sign(value.Real), 0);
    else
        return Complex.Tanh(value);
}

请参见https://dotnetfiddle.net/QvUECX

还有tan方法:

public static Complex Tan(Complex value)
{
    if (Math.Abs(value.Imaginary) > 20)
        return new Complex(0, Math.Sign(value.Imaginary));
    else
        return Complex.Tan(value);
}

请参见https://dotnetfiddle.net/Xzclcu