SRC: Комплексные числа на C#
От: Jenyay http://jenyay.net
Дата: 16.04.04 17:29
Оценка: 33 (2)
Ничего точти не делал под .NET. Вот слепил простенький класс сабжа. Просьба что-нибудь посоветовать, что не так, как это лучше сделать по-другому и т.п. Сделал их как сборку. Тестировал через Nunit. Сам проект лежит здесь и на всякий пожарный здесь.

Сам класс:
using System;

namespace Jenyay
{
    /// <summary>
    /// Класс комплексных чисел
    /// </summary>
    public class Complex : ICloneable
    {
        private double m_real = 0.0;
        private double m_imag = 0.0;

        #region Конструкторы
        public Complex()
        {
        }

        public Complex (double re)
        {
            m_real = re;
        }

        public Complex (double re, double im)
        {
            m_real = re;
            m_imag = im;
        }

        public Complex (Complex x)
        {
            m_real = x.Real;
            m_imag = x.Imag;
        }
        #endregion

        public double Real
        {
            get { return m_real; }
            set { m_real = value; }
        }

        public double Imag
        {
            get { return m_imag; }
            set {m_imag = value; }
        }

        public double Abs
        {
            get { return Math.Sqrt(m_imag * m_imag + m_real * m_real); }
        }

        public double Arg
        {
            get { return Math.Atan(m_imag / m_real); }
        }

        /// <summary>
        /// Получить комплексно-сопряженное число
        /// </summary>
        public Complex GetConjugate()
        {
            return new Complex (m_real, -m_imag);
        }

        public override string ToString()
        {
            string res = "";

            if (m_real != 0.0)
            {
                res = m_real.ToString();
            }

            if (m_imag != 0.0)
            {
                if (m_imag > 0)
                {
                    res += "+";
                }

                res += m_imag.ToString() + "i";
            }

            return res;
        }

        #region Перегруженные операторы сложения
        public static Complex operator + (Complex c1, Complex c2)
        {
            return new Complex (c1.Real + c2.Real, c1.Imag + c2.Imag);
        }

        public static Complex operator + (Complex c1, double c2)
        {
            return new Complex (c1.Real + c2, c1.Imag);
        }

        public static Complex operator + (double  c1, Complex c2)
        {
            return new Complex (c1 + c2.Real, c2.Imag);
        }
        #endregion


        #region Перегруженные операторы вычитания
        public static Complex operator - (Complex c1, Complex c2)
        {
            return new Complex (c1.Real - c2.Real, c1.Imag - c2.Imag);
        }

        public static Complex operator - (Complex c1, double c2)
        {
            return new Complex (c1.Real - c2, c1.Imag);
        }

        public static Complex operator - (double  c1, Complex c2)
        {
            return new Complex (c1 - c2.Real, -c2.Imag);
        }
        #endregion


        #region Перегруженные операторы умножения
        public static Complex operator * (Complex c1, Complex c2)
        {
            return new Complex (c1.Real * c2.Real - c1.Imag * c2.Imag,
                c1.Real * c2.Imag + c1.Imag * c2.Real);
        }

        public static Complex operator * (Complex c1, double c2)
        {
            return new Complex (c1.Real * c2, c1.Imag * c2);
        }

        public static Complex operator * (double c1, Complex c2)
        {
            return new Complex (c1 * c2.Real, c1 * c2.Imag);
        }
        #endregion


        #region Перегруженные операторы деления
        public static Complex operator / (Complex c1, Complex c2)
        {
            double Denominator = c2.Real * c2.Real + c2.Imag * c2.Imag;
            return new Complex ((c1.Real * c2.Real + c1.Imag * c2.Imag) / Denominator,
                (c2.Real * c1.Imag - c2.Imag * c1.Real) / Denominator);
        }

        public static Complex operator / (Complex c1, double c2)
        {
            return new Complex (c1.Real / c2, c1.Imag / c2);
        }

        public static Complex operator / (double c1, Complex c2)
        {
            double Denominator = c2.Real * c2.Real + c2.Imag * c2.Imag;
            return new Complex ((c1 * c2.Real) / Denominator, (-c2.Imag * c1) / Denominator);
        }
        #endregion

        public static bool operator == (Complex c1, Complex c2)
        {
            return c1.Real == c2.Real && c1.Imag == c2.Imag;
        }

        public static bool operator != (Complex c1, Complex c2)
        {
            return c1.Real != c2.Real || c1.Imag != c2.Imag;
        }

        public override bool Equals(object obj)
        {
            return this == (Complex)obj;
        }

        public override int GetHashCode()
        {
            return m_real.GetHashCode() + m_imag.GetHashCode();
        }


        #region ICloneable Members

        public object Clone()
        {
            return new Complex (this.m_real, this.m_imag);
        }

        #endregion
    }
}






Тесты:
using System;
using NUnit.Framework;

using Jenyay;

namespace ComplexTest
{
    /// <summary>
    /// Класс для теста комплексных чисел
    /// </summary>
    [TestFixture]
    public class ComplexTest
    {
        public ComplexTest()
        {
        }

        [Test]
        public void InitTest()
        {
            Complex c1 = new Complex();
            Assertion.Assert(c1.Real == 0.0 && c1.Imag == 0.0);

            Complex c2 = new Complex(2.1);
            Assertion.Assert(c2.Real == 2.1 && c2.Imag == 0.0);

            Complex c3 = new Complex (3.3, 4.4);
            Assertion.Assert(c3.Real == 3.3 && c3.Imag == 4.4);

            Complex c4 = new Complex (c3);
            Assertion.Assert(c4.Real == 3.3 && c4.Imag == 4.4);
        }

        [Test]
        public void CompareTest()
        {
            Complex c1 = new Complex (1.0, 2.0);
            Complex c2 = new Complex (3.0, 4.0);
            Complex c3 = new Complex (5.0, 6.0);

            c1 = (Complex)c2.Clone();
            Assertion.Assert(c1.Real == c2.Real && c1.Imag == c2.Imag);
            Assertion.Assert(c1 == c2);
            Assertion.Assert (c1 != c3);

            c1.Real = 5.0;
            c1.Imag = 6.0;
            Assertion.Assert(c1.Real != c2.Real && c1.Imag != c2.Imag);
            Assertion.Assert(c1 != c2);
            Assertion.Assert (c1 == c3);
        }

        [Test]
        public void MiscTest()
        {
            Complex c1 = new Complex (1.0, 5.0);
            Assertion.Assert(c1.ToString(), c1.Abs == Math.Sqrt(26.0) && c1.Real == 1.0 && c1.Imag == 5.0);

            Complex c2 = c1.GetConjugate();
            Assertion.Assert(c2.ToString(), c2.Real == 1.0 && c2.Imag == -5.0 &&
                c1.Real == 1.0 && c1.Imag == 5.0);

            c1 = new Complex (1.0, 5.0);
            c2 = new Complex (2.0, -4.0);
            Complex c3 = (c1 + c2 * c1) / c2;
            Assertion.Assert(c3.ToString(), c3.Real == 0.1 && c3.Imag == 5.7);

            double arg = c1.Arg;
            Assertion.Assert (arg.ToString(), arg - 1.373 < 0.001);
        }

        [Test]
        public void AdditionTest()
        {
            Complex c1 = new Complex(1.0, 3.0);
            Complex c2 = new Complex (5.0, 6.0);
            Complex c3 = c1 + c2;

            Assertion.Assert(c3.ToString(), c3.Real == 6.0 && c3.Imag == 9.0);

            c2 = c1 + 3.2;
            Assertion.Assert(c2.ToString(), c2.Real == 4.2 && c2.Imag == 3.0);

            c2 = 5.6 + c1;
            Assertion.Assert(c2.ToString(), c2.Real == 6.6 && c2.Imag == 3.0);

            c1 += 5;
            Assertion.Assert(c1.ToString(), c1.Real == 6.0 && c1.Imag == 3.0);

            c1 = new Complex (1.0, 2.5);
            c2 = new Complex (3.6, 5.6);
            c1 += c2;
            Assertion.Assert(c1.ToString(), c1.Real == 4.6 && c1.Imag == 8.1);

            c1 += c2;
            Assertion.Assert(c1.ToString(), c1.Real == 8.2 && c1.Imag == 13.7);

            c1 += 10;
            Assertion.Assert (c1.ToString(), c1.Real == 18.2 && c1.Imag == 13.7);
        }

        [Test]
        public void SubtractionTest()
        {
            Complex c1 = new Complex(1.0, 3.0);
            Complex c2 = new Complex (5.0, 6.0);
            Complex c3 = c1 - c2;
            Assertion.Assert(c3.ToString(), c3.Real == -4.0 && c3.Imag == -3.0);

            c3 = c1 - 2;
            Assertion.Assert(c3.ToString(), c3.Real == -1 && c3.Imag == 3.0);

            c3 = 5 - c1;
            Assertion.Assert(c3.ToString(), c3.Real == 4 && c3.Imag == -3.0);

            c1 -= c3;
            Assertion.Assert(c1.ToString(), c1.Real == -3 && c1.Imag == 6);

            c1 -= -13;
            Assertion.Assert(c1.ToString(), c1.Real == 10 && c1.Imag == 6);
        }

        [Test]
        public void MultiplicationTest()
        {
            Complex c1 = new Complex (1, -2);
            Complex c2 = new Complex (3, 2);
            Complex c3 = c1 * c2;
            Complex c4 = c2 * c1;

            Assertion.Assert(c3.Real == 7 && c3.Imag == -4);
            Assertion.Assert(c3 == c4);

            c2 = c1 * 3;
            Assertion.Assert(c2.Real == 3 && c2.Imag == -6);

            c2 = -5 * c1;
            Assertion.Assert(c2.Real == -5 && c2.Imag == 10);

            c2 *= c1;
            Assertion.Assert(c2.Real == 15 && c2.Imag == 20);

            c2 *= 0.2;
            Assertion.Assert (c2.ToString(), c2.Real == 3 && c2.Imag == 4);
        }

        [Test]
        public void DivisionTest()
        {
            Complex c1 = new Complex (7, -4);
            Complex c2 = new Complex (3, 2);
            Complex c3 = c1 / c2;

            Assertion.Assert(c3.ToString(), c3.Real == 1 && c3.Imag == -2);

            c1 = new Complex (10, 15);
            c2 = c1 / 5.0;
            Assertion.Assert(c2.ToString(), c2.Real == 2 && c2.Imag == 3);

            c1 = new Complex (1.0, -2.0);
            c2 = 2.0 / c1;
            Assertion.Assert(c2.ToString(), c2.Real == 0.4 && c2.Imag == 0.8);

            c1 /= 0.2;
            Assertion.Assert(c1.ToString(), c1.Real == 5 && c1.Imag == -10);

            c2.Real = 1;
            c2.Imag = 3;
            c1 /= c2;
            Assertion.Assert(c1.ToString(), c1.Real == -2.5 && c1.Imag == -2.5);
        }
    }
}
... << RSDN@Home 1.1.3 stable >>
Софт, исходники и фото
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.