微软公司内部培训程序员资料---操作复数类

/*
 * 操作复数的类Complex
 *
 * 周长发编制
 */
using System;

namespace MSAlgorithm
{
    /**
	 * 操作复数的类Complex

	 * @author 周长发
	 * @version 1.0
	 */
    public class Complex
    {
        /// <summary>
        /// 复数实部
        /// </summary>
        private double real = 0.0;

        /// <summary>
        /// 复数虚部
        /// </summary>
        private double imaginary = 0.0;

        /// <summary>
        /// 缺省精度
        /// </summary>
        private double eps = 0.0;

        /// <summary>
        /// 实部
        /// </summary>
        public double Real
        {
            get { return real; }
            set { real = value; }
        }

        /// <summary>
        /// 虚部
        /// </summary>
        public double Imaginary
        {
            get { return imaginary; }
            set { imaginary = value; }
        }

        /// <summary>
        /// 精度
        /// </summary>
        public double Eps
        {
            get { return eps; }
            set { eps = value; }
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        public Complex()
        { }

        /// <summary>
        /// 指定值构造函数
        /// </summary>
        /// <param name="dblX">指定的实部</param>
        /// <param name="dblY">指定的虚部</param>
        public Complex(double dblX, double dblY)
        {
            real = dblX;
            imaginary = dblY;
        }

        /// <summary>
        /// 拷贝构造函数
        /// </summary>
        /// <param name="other">源复数</param>
        public Complex(Complex other)
        {
            real = other.real;
            imaginary = other.imaginary;
        }

        /// <summary>
        /// 根据"a,b"形式的字符串来构造复数,以a为复数的实部,b为复数的虚部
        /// </summary>
        /// <param name="s">"a,b"形式的字符串,a为复数的实部,b为复数的虚部</param>
        /// <param name="sDelim">a, b之间的分隔符</param>
        public Complex(string s, string sDelim)
        {
            SetValue(s, sDelim);
        }

        /// <summary>
        /// 设置复数运算的精度
        /// </summary>
        /// <param name="newEps">新的精度值</param>
        public void SetEps(double newEps)
        {
            eps = newEps;
        }

        /// <summary>
        /// 取复数的精度值
        /// </summary>
        /// <returns>复数的精度值</returns>
        public double GetEps()
        {
            return eps;
        }

        /// <summary>
        /// 指定复数的实部
        /// </summary>
        /// <param name="dblX">复数的实部</param>
        public void SetReal(double dblX)
        {
            real = dblX;
        }

        /// <summary>
        /// 指定复数的虚部
        /// </summary>
        /// <param name="dblY">复数的虚部</param>
        public void SetImag(double dblY)
        {
            imaginary = dblY;
        }

        /// <summary>
        /// 取复数的实部
        /// </summary>
        /// <returns>复数的实部</returns>
        public double GetReal()
        {
            return real;
        }

        /// <summary>
        /// 取复数的虚部
        /// </summary>
        /// <returns>复数的虚部</returns>
        public double GetImag()
        {
            return imaginary;
        }

        /// <summary>
        /// 指定复数的实部和虚部值
        /// </summary>
        /// <param name="real">指定的实部</param>
        /// <param name="imag">指定的虚部</param>
        public void SetValue(double real, double imag)
        {
            SetReal(real);
            SetImag(imag);
        }

        /// <summary>
        /// 将"a,b"形式的字符串转化为复数,以a为复数的实部,b为复数的虚部
        /// </summary>
        /// <param name="s">"a,b"形式的字符串,a为复数的实部,b为复数的虚部</param>
        /// <param name="sDelim">a, b之间的分隔符</param>
        public void SetValue(string s, string sDelim)
        {
            int nPos = s.IndexOf(sDelim);
            if (nPos == -1)
            {
                s = s.Trim();
                real = double.Parse(s);
                imaginary = 0;
            }
            else
            {
                int nLen = s.Length;
                string sLeft = s.Substring(0, nPos);
                string sRight = s.Substring(nPos + 1, nLen - nPos - 1);
                sLeft = sLeft.Trim();
                sRight = sRight.Trim();
                real = double.Parse(sLeft);
                imaginary = double.Parse(sRight);
            }
        }

        /// <summary>
        /// 重载 + 运算
        /// </summary>
        /// <param name="cpx1">指定的复数1</param>
        /// <param name="cpx2">指定的复数2</param>
        /// <returns>Complex对象</returns>
        public static Complex operator +(Complex cpx1, Complex cpx2)
        {
            return cpx1.Add(cpx2);
        }

        /// <summary>
        ///  重载 - 运算符
        /// </summary>
        /// <param name="cpx1">指定的复数1</param>
        /// <param name="cpx2">指定的复数2</param>
        /// <returns>Complex对象</returns>
        public static Complex operator -(Complex cpx1, Complex cpx2)
        {
            return cpx1.Subtract(cpx2);
        }

        /// <summary>
        /// 重载 * 运算符
        /// </summary>
        /// <param name="cpx1">指定的复数1</param>
        /// <param name="cpx2">指定的复数2</param>
        /// <returns>Complex对象</returns>
        public static Complex operator *(Complex cpx1, Complex cpx2)
        {
            return cpx1.Multiply(cpx2);
        }

        /// <summary>
        /// 重载 / 运算符
        /// </summary>
        /// <param name="cpx1">指定的复数1</param>
        /// <param name="cpx2">指定的复数2</param>
        /// <returns></returns>
        public static Complex operator /(Complex cpx1, Complex cpx2)
        {
            return cpx1.Divide(cpx2);
        }

        /// <summary>
        /// 重载 double 运算符
        /// </summary>
        /// <param name="cpx">指定的复数</param>
        /// <returns>double值</returns>
        public static implicit operator double(Complex cpx)
        {
            return cpx.Abs();
        }

        /// <summary>
        /// 将复数转化为"a+bj"形式的字符串
        /// </summary>
        /// <returns>string 型,"a+bj"形式的字符串</returns>
        public override string ToString()
        {
            string s;
            if (real != 0.0)
            {
                if (imaginary > 0)
                    s = real.ToString("F") + "+" + imaginary.ToString("F") + "j";
                else if (imaginary < 0)
                {
                    double absImag = -1 * imaginary;
                    s = real.ToString("F") + "-" + absImag.ToString("F") + "j";
                }
                else
                    s = real.ToString("F");
            }
            else
            {
                if (imaginary > 0)
                    s = imaginary.ToString("F") + "j";
                else if (imaginary < 0)
                {
                    double absImag = -1 * imaginary;
                    s = absImag.ToString("F") + "j";
                }
                else
                    s = real.ToString("F");
            }

            return s;
        }

        /// <summary>
        /// 比较两个复数是否相等
        /// </summary>
        /// <param name="other">用于比较的复数</param>
        /// <returns> bool型,相等则为true,否则为false</returns>
        public override bool Equals(object other)
        {
            Complex cpxX = other as Complex;
            if (cpxX == null)
                return false;
            return Math.Abs(real - cpxX.real) <= eps &&
                Math.Abs(imaginary - cpxX.imaginary) <= eps;
        }

        /// <summary>
        /// 因为重写了Equals,因此必须重写GetHashCode
        /// </summary>
        /// <returns>int型,返回复数对象散列码</returns>
        public override int GetHashCode()
        {
            return (int)Math.Sqrt(real * real + imaginary * imaginary);
        }

        /// <summary>
        /// 给复数赋值
        /// </summary>
        /// <param name="cpxX">用于给复数赋值的源复数</param>
        /// <returns>Complex型,与cpxX相等的复数</returns>
        public Complex SetValue(Complex cpxX)
        {
            real = cpxX.real;
            imaginary = cpxX.imaginary;

            return this;
        }

        /// <summary>
        /// 实现复数的加法
        /// </summary>
        /// <param name="cpxX">与指定复数相加的复数</param>
        /// <returns>指定复数与cpxX相加之和</returns>
        public Complex Add(Complex cpxX)
        {
            double x = real + cpxX.real;
            double y = imaginary + cpxX.imaginary;
            return new Complex(x, y);
        }

        /// <summary>
        /// 实现复数的减法
        /// </summary>
        /// <param name="cpxX">与指定复数相减的复数</param>
        /// <returns>指定复数减去cpxX之差</returns>
        public Complex Subtract(Complex cpxX)
        {
            double x = real - cpxX.real;
            double y = imaginary - cpxX.imaginary;
            return new Complex(x, y);
        }

        /// <summary>
        /// 实现复数的乘法
        /// </summary>
        /// <param name="cpxX">与指定复数相乘的复数</param>
        /// <returns>指定复数与cpxX相乘之积</returns>
        public Complex Multiply(Complex cpxX)
        {
            double x = real * cpxX.real - imaginary * cpxX.imaginary;
            double y = imaginary * cpxX.real + real * cpxX.imaginary;
            return new Complex(x, y);
        }

        /// <summary>
        /// 实现复数的除法
        /// </summary>
        /// <param name="cpxX">与指定复数相除的复数</param>
        /// <returns>指定复数除与cpxX之商</returns>
        public Complex Divide(Complex cpxX)
        {
            double e, f, x, y;

            if (Math.Abs(cpxX.real) >= Math.Abs(cpxX.imaginary))
            {
                e = cpxX.imaginary / cpxX.real;
                f = cpxX.real + e * cpxX.imaginary;

                x = (real + imaginary * e) / f;
                y = (imaginary - real * e) / f;
            }
            else
            {
                e = cpxX.real / cpxX.imaginary;
                f = cpxX.imaginary + e * cpxX.real;

                x = (real * e + imaginary) / f;
                y = (imaginary * e - real) / f;
            }

            return new Complex(x, y);
        }

        /// <summary>
        /// 计算复数的模
        /// </summary>
        /// <returns>double型,指定复数的模</returns>
        public double Abs()
        {
            //求取实部和虚部的绝对值
            double x = Math.Abs(real);
            double y = Math.Abs(imaginary);

            if (real == 0)
                return y;
            if (imaginary == 0)
                return x;

            //计算模
            if (x > y)
                return (x * Math.Sqrt(1 + (y / x) * (y / x)));

            return (y * Math.Sqrt(1 + (x / y) * (x / y)));
        }

        /// <summary>
        /// 计算复数的根
        /// </summary>
        /// <param name="n">待求根的根次</param>
        /// <param name="cpxR">Complex型数组,长度为n,返回复数的所有根</param>
        public void Root(int n, Complex[] cpxR)
        {
            if (n < 1)
                return;

            double q = Math.Atan2(imaginary, real);
            double r = Math.Sqrt(real * real + imaginary * imaginary);
            if (r != 0)
            {
                r = (1.0 / n) * Math.Log(r);
                r = Math.Exp(r);
            }

            for (int k = 0; k <= n - 1; k++)
            {
                double t = (2.0 * k * 3.1415926 + q) / n;
                cpxR[k] = new Complex(r * Math.Cos(t), r * Math.Sin(t));
            }
        }

        /// <summary>
        /// 计算复数的实幂指数
        /// </summary>
        /// <param name="dblW">待求实幂指数的幂次</param>
        /// <returns>Complex型,复数的实幂指数值</returns>
        public Complex Pow(double dblW)
        { 
            //常量
            const double PI = 3.14159265358979;

            double r, t;

            //特殊值处理
            if ((real == 0) && (imaginary == 0))
                return new Complex(0, 0);

            //幂运算公式中的三角函数运算
            if (real == 0)
            {
                if (imaginary > 0)
                    t = 1.5707963268;
                else
                    t = -1.5707963268;
            }
            else
            {
                if (real > 0)
                    t = Math.Atan2(imaginary, real);
                else
                {
                    if (imaginary >= 0)
                        t = Math.Atan2(imaginary, real) + PI;
                    else
                        t = Math.Atan2(imaginary, real) - PI;
                }
            }

            //模的幂
            r = Math.Exp(dblW * Math.Log(Math.Sqrt(real * real + imaginary * imaginary)));

            //复数的实幂指数
            return new Complex(r * Math.Cos(dblW * t), r * Math.Sin(dblW * t));
        }

        /// <summary>
        /// 计算复数的复幂指数
        /// </summary>
        /// <param name="cpxW">待求复幂指数的幂次</param>
        /// <param name="n">控制参数,默认值为0。当n=0时,求得的结果为复幂指数的主值</param>
        /// <returns>Complex型,复数的复幂指数值</returns>
        public Complex Pow(Complex cpxW, int n)
        { 
            //常量
            const double PI = 3.14159265358979;

            double r, s, u, v;

            //特殊值处理
            if (real == 0)
            {
                if (imaginary == 0)
                    return new Complex(0, 0);

                s = 1.5707963268 * (Math.Abs(imaginary) / imaginary + 4 * n);
            }
            else
            {
                s = 2 * PI * n + Math.Atan2(imaginary, real);

                if (real < 0)
                {
                    if (imaginary > 0)
                        s = s + PI;
                    else
                        s = s - PI;
                }
            }

            //求幂运算公式
            r = 0.5 * Math.Log(real * real + imaginary * imaginary);
            v = cpxW.real * r + cpxW.imaginary * s;
            u = Math.Exp(cpxW.real * r - cpxW.imaginary * s);

            return new Complex(u * Math.Cos(v), u * Math.Sin(v));
        }

        /// <summary>
        /// 计算复数的自然对数
        /// </summary>
        /// <returns>Complex型,复数的自然对数值</returns>
        public Complex Log()
        {
            double p = Math.Log(Math.Sqrt(real * real + imaginary * imaginary));
            return new Complex(p, Math.Atan2(imaginary, real));
        }

        /// <summary>
        /// 计算复数的正弦
        /// </summary>
        /// <returns>Complex型,复数的正弦值</returns>
        public Complex Sin()
        {
            int i;
            double x, y, y1, br, b1, b2;
            double[] c = new double[6];

            //切比雪夫公式的常数系数
            c[0] = 1.13031820798497;
            c[1] = 0.04433684984866;
            c[2] = 0.00054292631191;
            c[3] = 0.00000319843646;
            c[4] = 0.00000001103607;
            c[5] = 0.00000000002498;

            y1 = Math.Exp(imaginary);
            x = 0.5 * (y1 + 1 / y1);
            br = 0;
            if (Math.Abs(imaginary) >= 1)
                y = 0.5 * (y1 - 1 / y1);
            else
            {
                b1 = 0;
                b2 = 0;
                y1 = 2 * (2 * imaginary * imaginary - 1);
                for (i = 5; i >= 0; --i)
                {
                    br = y1 * b1 - b2 - c[i];
                    if (i != 0)
                    {
                        b2 = b1;
                        b1 = br;
                    }
                }

                y = imaginary * (br - b1);
            }

            //组合计算结果
            x = x * Math.Sin(real);
            y = y * Math.Cos(real);

            return new Complex(x, y);
        }

        /// <summary>
        /// 计算复数的余弦
        /// </summary>
        /// <returns>Complex型,复数的余弦值</returns>
        public Complex Cos()
        {
            int i;
            double x, y, y1, br, b1, b2;
            double[] c = new double[6];

            //切比雪夫公式的常数系数
            c[0] = 1.13031820798497;
            c[1] = 0.04433684984866;
            c[2] = 0.00054292631191;
            c[3] = 0.00000319843646;
            c[4] = 0.00000001103607;
            c[5] = 0.00000000002498;

            y1 = Math.Exp(imaginary);
            x = 0.5 * (y1 + 1 / y1);
            br = 0;
            if (Math.Abs(imaginary) >= 1)
                y = 0.5 * (y1 - 1 / y1);
            else
            {
                b1 = 0;
                b2 = 0;
                y1 = 2 * (2 * imaginary * imaginary - 1);
                for (i = 5; i >= 0; i--)
                {
                    br = y1 * b1 - b2 - c[i];
                    if (i != 0)
                    {
                        b2 = b1;
                        b1 = br;
                    }
                }

                y = imaginary * (br - b1);
            }

            //组合计算结果
            x = x * Math.Cos(real);
            y = -y * Math.Sin(real);

            return new Complex(x, y);
        }

        /// <summary>
        /// 计算复数的正切
        /// </summary>
        /// <returns>Complex型,复数的正切值</returns>
        public Complex Tan()
        {
            return Sin().Divide(Cos());
        }
    }
}


注:本代码为原作者所有,本人只是摘录,如有侵犯作者,请与本人联系

Email:359194966@qq.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值