代码之家  ›  专栏  ›  技术社区  ›  Wollmich

c复tanh对大值无效

  •  2
  • Wollmich  · 技术社区  · 6 年前

    这是来自Microsoft的实现 Sinh A的 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

    public static Complex Tanh(Complex value) /* Hyperbolic tan */
    {
        return (Sinh(value) / Cosh(value));
    }
    

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

    我不明白为什么微软实施了 坦赫 这样的方法?

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

    • tanh(709 + 0i) --> 1 好吧
    • tanh(711 + 0i) --> NaN ,失败应为1

    有什么想法如何改进 tanh 方法呢?

    为了 double 这个 Math.Tanh 方法适用于较大的值。

    2 回复  |  直到 6 年前
        1
  •  2
  •   Wollmich    6 年前

    情结 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 .

        2
  •  0
  •   Wollmich    6 年前

    使用HansPassant的注释另一种方法来实现 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 .