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 >>
Софт, исходники и фото
Re: SRC: Комплексные числа на C#
От: vdimas Россия  
Дата: 19.04.04 11:37
Оценка:
Здравствуйте, Jenyay, Вы писали:

J>Ничего точти не делал под .NET. Вот слепил простенький класс сабжа. Просьба что-нибудь посоветовать, что не так, как это лучше сделать по-другому и т.п.


1. А почему не value type???
Re[2]: SRC: Комплексные числа на C#
От: Jenyay http://jenyay.net
Дата: 19.04.04 16:02
Оценка:
Здравствуйте, vdimas, Вы писали:

V>1. А почему не value type???


Я тоже об этом подумал, когда перечитал статью из какого-то выпуска RSDN про value и ссылочные типы. Как будет время — подправлю.
... << RSDN@Home 1.1.3 stable >>
Софт, исходники и фото
Re[2]: SRC: Комплексные числа на C#
От: Jenyay http://jenyay.net
Дата: 22.04.04 16:06
Оценка:
Здравствуйте, vdimas, Вы писали:


V>1. А почему не value type???


Вот если так? Сам проект лежит там же. Не думал, что придется так мало исправлять

Сам класс, т.е. теперь структура:

using System;

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

        #region Конструкторы

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

        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();
        }
    }
}



И тест:

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 = c2;
            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 >>
Софт, исходники и фото
Re[3]: SRC: Комплексные числа на C#
От: vdimas Россия  
Дата: 23.04.04 12:50
Оценка:
Здравствуйте, Jenyay, Вы писали:

да, вполне,
тогда давай уже и следующее :
— корень квадратный
— степень
— экспонента
— добавь структуру Polar в тот же namespace и пусть у тебя будет св-во Polar в комплексном числе и св-во Complex в структуре Polar для взаимного преобразования, и плюс надо определить операторы взаимного преобразования
— все "простые" типы должны иметь метод Parse, который обратен по смыслу ToString
— сделай TypeConverter для Complex, чтобы им можно было пользоваться в качестве полей, доступных для визуального редактирования Property-гридом
— добавь readonly статическую константу — j (0, j1);
— добавь статические методы, для работы с реальными числами, но возвращающими Complex,
напр: Complex i=Complex.Sqrt(-1);
Re: SRC: Комплексные числа на C#
От: c-smile Канада http://terrainformatica.com
Дата: 23.04.04 16:00
Оценка: 12 (1) +1
Здравствуйте, Jenyay, Вы писали:


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


Идологически этот метод exception порождать не должен.
Или я не прав?
Re[2]: SRC: Комплексные числа на C#
От: BiТ  
Дата: 23.04.04 16:11
Оценка: 12 (1)
Здравствуйте, c-smile, Вы писали:

CS>Здравствуйте, Jenyay, Вы писали:



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


CS>Идологически этот метод exception порождать не должен.

CS>Или я не прав?

В данном куске кода если obj.GetType() != typeof(Complex) — то будет сгенерировано исключение InvalidCastException — что есть плохо.
А должно быть что-то вроде:

public override bool Equals(object obj)
{
   if (obj == null || obj.GetType() != this.GetType)
       return false;
   // Дальше идут проверки полей класса.
}


И кстати — подобные вещи Рихтером обмусолены до дыр — уже даже второе издание его труда "Разработка приложений для .NET" вышло
Re[3]: SRC: Комплексные числа на C#
От: Jenyay http://jenyay.net
Дата: 23.04.04 16:44
Оценка:
Здравствуйте, BiТ, Вы писали:

BiТ>В данном куске кода если obj.GetType() != typeof(Complex) — то будет сгенерировано исключение InvalidCastException — что есть плохо.

BiТ>А должно быть что-то вроде:

BiТ>
BiТ>public override bool Equals(object obj)
BiТ>{
BiТ>   if (obj == null || obj.GetType() != this.GetType)
BiТ>       return false;
BiТ>   // Дальше идут проверки полей класса.
BiТ>}
BiТ>


BiТ>И кстати — подобные вещи Рихтером обмусолены до дыр — уже даже второе издание его труда "Разработка приложений для .NET" вышло


Спасибо ОГРОМНОЕ. Буду знать. До рихтера руки покане дошли — надеюсь после сессии дойдут. Пока особо не до программирования. А на русском вышло?
... << RSDN@Home 1.1.3 stable >>
Софт, исходники и фото
Re[4]: SRC: Комплексные числа на C#
От: Jenyay http://jenyay.net
Дата: 23.04.04 16:44
Оценка:
Здравствуйте, vdimas, Вы писали:

V>- сделай TypeConverter для Complex, чтобы им можно было пользоваться в качестве полей, доступных для визуального редактирования Property-гридом


А можно про это поподробнее? Что это такое?

А так тогда сюда буду писать по мере продвижения.
... << RSDN@Home 1.1.3 stable >>
Софт, исходники и фото
Re[2]: SRC: Комплексные числа на C#
От: Jenyay http://jenyay.net
Дата: 23.04.04 16:48
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Идологически этот метод exception порождать не должен.

CS>Или я не прав?

А в двух словах почему? И где еще не должно быть exception?
... << RSDN@Home 1.1.3 stable >>
Софт, исходники и фото
Re[4]: SRC: Комплексные числа на C#
От: BiТ  
Дата: 23.04.04 18:11
Оценка:
Здравствуйте, Jenyay, Вы писали:

J>Здравствуйте, BiТ, Вы писали:


>> А на русском вышло?


Да. Лично я только первое издание читал. Разницу между первым и вторым изданием не знаю.
Re: SRC: Комплексные числа на C#
От: Jenyay http://jenyay.net
Дата: 28.04.04 16:43
Оценка:
Закачал сюда изменунные классы. Добавил структуру Polar, вычисление корней и исправил баг в определении аргумента.
... << RSDN@Home 1.1.3 stable >>
Софт, исходники и фото
Re: SRC: Комплексные числа на C#
От: Jenyay http://jenyay.net
Дата: 30.04.04 15:34
Оценка:
Вот, довел до ума класс по советам vdimas Re[3]: SRC: Комплексные числа на C#
Автор: vdimas
Дата: 23.04.04
.

Какие будут замечания?

Исходники лежат по адресу http://jenyay.wallst.ru/classes/ComplexTest.zip. А вот текст.

Complex.cs:
using System;

namespace Jenyay
{
    /// <summary>
    /// Класс комплексных чисел
    /// </summary>
    public struct Complex
    {
        /// <summary>
        /// Бросаемое исключение при неудачном парсинге строки
        /// </summary>
        public class ParseError : System.Exception
        {
            /// <summary>
            /// Строка, из-за которой произошло исключение
            /// </summary>
            private string m_ErrString;

            public ParseError(string str)
            {
                m_ErrString = str;
            }

            public override string Message
            {
                get
                {
                    return "Не могу распарсить строку \"" + m_ErrString + "\"";
                }
            }

        }

        private double m_real;
        private double m_imag;

        #region Конструкторы

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

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

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

        public Complex (Polar x)
        {
            m_real = x.R * Math.Cos(x.Phi);
            m_imag = x.R * Math.Sin(x.Phi);
        }
        #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); }
        }


        /// <summary>
        /// Аргумент числа в интервале [0; 2* pi)
        /// </summary>
        public double Arg
        {
            get 
            { 
                double res = Math.Atan2(m_imag, m_real);
                if (res < 0)
                {
                    res += Math.PI;
                }
                return res; 
            }
        }

        /// <summary>
        /// Константа 0 + j
        /// </summary>
        public static Complex J
        {
            get
            {
                return new Complex(0, 1);
            }
        }

        /// <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

        #region Операторы сравнения
        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)
        {
            if (obj == null || obj.GetType() != this.GetType())
            {
                return false;
            }

            return this == (Complex)obj;
        }
        #endregion

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

        public Polar Polar
        {
            get
            {
                return new Polar(this);
            }
            set
            {
                m_real = value.R * Math.Cos(value.Phi);
                m_imag = value.R * Math.Sin(value.Phi);
            }
        }

        /// <summary>
        /// Считает квадратный корень
        /// </summary>
        /// <param name="c">Число, из которого считают корень</param>
        /// <returns></returns>
        public static Complex Sqrt (Complex c)
        {
            double abs = Math.Sqrt(c.Abs);
            return new Complex (abs * Math.Cos(c.Arg / 2), abs * Math.Sin(c.Arg / 2));
        }

        public static Complex Sqrt(double x)
        {
            // По идее, если x < 0, то рез-т должен быть +- a*i, но все-таки возвращаем только с +.
            return x >= 0 ? new Complex(Math.Sqrt(x)) : new Complex (0, Math.Sqrt(-x));
        }

        /// <summary>
        /// Считает все корни степени n (n штук)
        /// </summary>
        /// <param name="c">Число, из которого извлекаем корень</param>
        /// <param name="n">Степень корня</param>
        /// <returns>Массив с результатами</returns>
        public static Complex[] Radical (Complex c, int n)
        {
            Complex[] res = new Complex[n];

            double abs = Math.Pow(c.Abs, 1.0 / n);

            // Начальный угол
            double Phi0 = c.Arg / n;

            // Шаг по углу
            double dPhi = 2 * Math.PI / n;

            for (int i = 0; i < n; ++i)
            {
                double CurrPhi = Phi0 + i * dPhi;
                res[i] = new Complex(abs * Math.Cos(CurrPhi), abs * Math.Sin(CurrPhi));
            }

            return res;
        }


        /// <summary>
        /// Создает переменную типа Complex из строки
        /// </summary>
        /// <param name="str">Строка, по которой создаем переменную</param>
        /// <returns>Полученную переменную или бросает исключение в случае неудачи</returns>
        public static Complex CreateFromString(string str)
        {
            /*
             Возможные варианты строк:
             1+5i
             1 + 5i
             +1 + 5i
             -1 - 5i
             -5
             -6i
             +6i
             i
             1+i
             -i
            */

            // В качестве i может быть написано j и может быть любое число пробелов

            // 1. Удаляем все пробелы
            string TempStr = str.Replace(" ", "");

            // 2. Заменяем j на i
            TempStr = TempStr.Replace("j", "i");

            // 3. Находим мнимую часть
            double imag = 0;

            // Если последний символ - i, значит мнимая часть есть
            int pos = TempStr.Length - 1;
            if (TempStr[TempStr.Length - 1] == 'i')
            {
                string ImagStr = "";

                for (pos--; pos >= 0; --pos)
                {
                    char CurrChar = TempStr[pos];

                    // Если идет число, то просто добавляем символ в начало
                    if (CurrChar >= '0' && CurrChar <= '9')
                    {
                        ImagStr = CurrChar + ImagStr;
                    }
                    else if (CurrChar == '+' || CurrChar == '-')
                    {
                        // Если знак, то добавляем его и обрываем цикл
                        ImagStr = CurrChar + ImagStr;

                        // Если строка теперь состоит из одного знака, то добавим 1
                        if (ImagStr.Length == 1)
                        {
                            ImagStr += "1";
                        }
                        break;
                    }
                    else
                    {
                        // Если что-то другое, значит ошибка
                        throw new ParseError(str);
                    }
                }

                if (ImagStr.Length == 0)
                {
                    imag = 1.0;
                }
                else
                {
                    imag = Convert.ToDouble(ImagStr);
                }
                pos--;
            }

            // 4. Получаем реальную часть
            double real = 0;
            // Если еще может быть реальная часть
            if (pos >= 0)
            {

                // Если дальше идет число
                if (TempStr[pos] >= '0' && TempStr[pos] <= '9')
                {
                    string RealStr = TempStr[pos].ToString();

                    for (pos--; pos >= 0; --pos)
                    {
                        char CurrChar = TempStr[pos];

                        // Если идет число, то просто добавляем символ в начало
                        if (CurrChar >= '0' && CurrChar <= '9')
                        {
                            RealStr = CurrChar + RealStr;
                        }
                        else if (CurrChar == '+' || CurrChar == '-')
                        {
                            // Если знак, то добавляем его и обрываем цикл
                            RealStr = CurrChar + RealStr;
                            break;
                        }
                        else
                        {
                            // Если что-то другое, значит ошибка
                            throw new ParseError(str);
                        }
                    }

                    real = Convert.ToDouble(RealStr);
                }
                else
                {
                    throw new ParseError(str);
                }
            }

            return new Complex(real, imag);
        }

        /// <summary>
        /// Вычисление экспоненты комплексного числа
        /// </summary>
        /// <param name="c">Число от которого ищут экспоненту</param>
        public static Complex Exp (Complex c)
        {
            return new Complex (new Polar(Math.Exp(c.Real), c.Imag) );
        }


        /// <summary>
        /// Возведение комплексного числа в степень
        /// </summary>
        /// <param name="n">Степень в которую возводим число</param>
        public static Complex Pow (Complex c, int n)
        {
            double NewArg = c.Arg * n;
            double NewAbs = 1;
            for (int i = 0; i < n; ++i)
            {
                NewAbs *= c.Abs;
            }

            return new Complex (new Polar (NewAbs, NewArg) );
        }
    }
}


Polar.cs:
using System;

namespace Jenyay
{
    /// <summary>
    /// Полярное приедставление комплексного числа
    /// </summary>
    public struct Polar
    {
        /// <summary>
        /// Радиус, по сути модуль
        /// </summary>
        private double m_r;

        /// <summary>
        /// Угол
        /// </summary>
        private double m_phi;

        #region Конструкторы

        public Polar (double r)
        {
            m_r = r;
            m_phi = 0.0;
        }

        public Polar (double r, double phi)
        {
            m_r = r;
            m_phi = phi;
        }

        public Polar (Complex x)
        {
            m_r = x.Abs;
            m_phi = x.Arg;
        }
        #endregion

        public Complex Complex
        {
            get
            {
                return new Complex(this);
            }

            set
            {
                m_r = value.Abs;
                m_phi = value.Arg;
            }
        }

        public double R
        {
            get { return m_r; }
            set { m_r = value; }
        }

        public double Phi
        {
            get { return m_phi; }
            set { m_phi = value; }
        }

        public override string ToString()
        {
            return "r=" + m_r.ToString() + " phi=" + m_phi.ToString();
        }

        public static implicit operator Complex (Polar p)
        {
            return new Complex(p);
        }

        public static explicit operator Polar (Complex c)
        {
            return new Polar(c);
        }

    }
}


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

using Jenyay;

namespace ComplexTest
{
    /// <summary>
    /// Класс для теста полярного представления комплексных чисел
    /// </summary>
    [TestFixture]
    public class PolarTest
    {
        [Test]
        public void InitTest()
        {
            Polar p1 = new Polar(1.0, 2.0);
            Assertion.Assert (p1.R == 1.0 && p1.Phi == 2.0);

            Polar p2 = new Polar(3.0);
            Assertion.Assert (p2.R == 3.0 && p2.Phi == 0.0);

            Complex c1 = new Complex (2.0, 2.0);
            Polar p3 = new Polar (c1);
            Assertion.Assert(p3.ToString(), p3.R == Math.Sqrt(8.0) && p3.Phi - Math.PI / 4.0 < 0.0001);

            Complex c3 =  new Complex (p3);
            Assertion.Assert(c3.ToString(), c3.Real - 2.0 < 0.000001 && c3.Imag - 2.0 < 0.000001);
        }

        [Test]
        public void OperatorsTest()
        {
            Complex c1  = new Complex (1, 2);
            Complex c2 = new Complex (2, 3);

            Polar p1 = new Polar (c2);

            Complex c3 = c1 + p1;
            Assertion.Assert(c3.ToString(), c3.Real == 3.0 && c3.Imag == 5.0);

            Complex c4 = p1 + c1;
            Assertion.Assert(c4.ToString(), c4.Real == 3.0 && c4.Imag == 5.0);


            Complex c5 = c1 - p1;
            Assertion.Assert(c5.ToString(), c5 == c1 - c2);

            Complex c6 = p1 - c1;
            Assertion.Assert(c6.ToString(), c6 == c2 - c1);


            Complex c7 = c1 * p1;
            Assertion.Assert(c7.ToString(), c7 == c1 * c2);

            Complex c8 = p1 * c1;
            Assertion.Assert(c8.ToString(), c8 == c2 * c1);


            Complex c9 = c1 / p1;
            Assertion.Assert(c9.ToString(), c9 == c1 / c2);

            Complex c10 = p1 / c1;
            Assertion.Assert(c10.ToString(), c10 == c2 / c1);

            
            Complex c11 = new Complex(2, 2);
            Assertion.Assert (((Polar)c11).R == Math.Sqrt(8.0) && 
                ((Polar)c11).Phi - Math.PI / 4.0 < 0.0001);

            Polar p2 = new Polar(c11);
            Assertion.Assert(((Complex)p2).Abs == p2.R);
        }
    }
    

    /// <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 = c2;
            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);

            Complex c8 = new Complex (1, 1);
            Assertion.Assert (c8.Arg.ToString(), c8.Arg - 0.785 < 0.001);

            Complex c9 = new Complex (-1, 1);
            Assertion.Assert (c9.Arg.ToString(), c9.Arg - 2.356 < 0.001);

            Complex c10 = new Complex (-1, -1);
            Assertion.Assert (c10.Arg.ToString(), c10.Arg - 3.927 < 0.001);

            Complex c11 = new Complex (1, -1);
            Assertion.Assert (c11.Arg.ToString(), c11.Arg - 5.498 < 0.001);

            // Проверка квадратного корня
            Complex c4 = new Complex(1, 4);
            Complex c5 = Complex.Sqrt(c4);
            Assertion.Assert(c5.ToString(), c5.Real - 1.6 < 0.01 && c5.Imag - 1.25 < 0.01);

            Complex c6 = Complex.Sqrt(-9);
            Assertion.Assert(c6.ToString(), c6.Real == 0 && c6.Imag == 3);

            Complex c7 = Complex.Sqrt(4);
            Assertion.Assert(c7.ToString(), c7.Real == 2 && c7.Imag == 0);

            // Проверка константы j
            Complex c12 = Complex.J;
            Assertion.Assert (c12.ToString(), c12.Real == 0 && c12.Imag == 1);

            Complex c13 = new Complex(2, 3);
            Complex c14 = c13 + Complex.J;
            Assertion.Assert(c14.ToString(), c14.Real == 2 && c14.Imag == 4);
        }

        [Test]
        public void RadicalTest()
        {
            Complex c1 = new Complex(-8, 8 * Math.Sqrt(3));
            Complex[] CArr = Complex.Radical(c1, 4);
            Assertion.Assert (CArr.Length == 4);
            Assertion.Assert (CArr[0].ToString(), Math.Abs(CArr[0].Real - Math.Sqrt(3)) < 0.0001 && CArr[0].Imag == 1);
            Assertion.Assert (CArr[1].ToString(), Math.Abs(CArr[1].Real + 1) < 0.001 && Math.Abs(CArr[1].Imag - Math.Sqrt(3)) < 0.0001);
            Assertion.Assert(CArr[2].ToString(), Math.Abs(CArr[2].Real + Math.Sqrt(3)) < 0.0001 && Math.Abs(CArr[2].Imag + 1) < 0.0001);
            Assertion.Assert(CArr[3].ToString(), Math.Abs(CArr[3].Real - 1) < 0.0001 && Math.Abs(CArr[3].Imag + Math.Sqrt(3)) < 0.0001);
        }

        [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);
        }

        [Test]
        public void ParseTest()
        {
            Complex c1 = Complex.CreateFromString("5 + 6i");
            Assertion.Assert(c1.ToString(), c1.Real == 5 && c1.Imag == 6);

            Complex c2 = Complex.CreateFromString("65 - 61j");
            Assertion.Assert(c2.ToString(), c2.Real == 65 && c2.Imag == -61);

            Complex c3 = Complex.CreateFromString("+100 - 02j");
            Assertion.Assert(c3.ToString(), c3.Real == 100 && c3.Imag == -2);

            Complex c4 = Complex.CreateFromString("2 + j");
            Assertion.Assert(c4.ToString(), c4.Real == 2 && c4.Imag == 1);

            Complex c5 = Complex.CreateFromString("3 - j");
            Assertion.Assert(c5.ToString(), c5.Real == 3 && c5.Imag == -1);

            Complex c6 = Complex.CreateFromString("5");
            Assertion.Assert(c6.ToString(), c6.Real == 5 && c6.Imag == 0);

            Complex c7 = Complex.CreateFromString("-78");
            Assertion.Assert(c7.ToString(), c7.Real == -78 && c7.Imag == 0);

            Complex c8 = Complex.CreateFromString("j");
            Assertion.Assert(c8.ToString(), c8.Real == 0 && c8.Imag == 1);

            Complex c9 = Complex.CreateFromString("-j");
            Assertion.Assert(c9.ToString(), c9.Real == 0 && c9.Imag == -1);

            Complex c10 = Complex.CreateFromString("5j");
            Assertion.Assert(c10.ToString(), c10.Real == 0 && c10.Imag == 5);

            Complex c11 = Complex.CreateFromString("11j");
            Assertion.Assert(c11.ToString(), c11.Real == 0 && c11.Imag == 11);

            Complex c12 = Complex.CreateFromString("-1j");
            Assertion.Assert(c12.ToString(), c12.Real == 0 && c12.Imag == -1);

            Complex c13 = Complex.CreateFromString("-23j");
            Assertion.Assert(c13.ToString(), c13.Real == 0 && c13.Imag == -23);
        }

        [Test, ExpectedException(typeof (Complex.ParseError))]
        public void ParseTest2()
        {
            Complex.CreateFromString("dsfsd34");
        }

        [Test, ExpectedException(typeof (Complex.ParseError))]
        public void ParseTest3()
        {
            Complex.CreateFromString("+");
        }

        [Test, ExpectedException(typeof (Complex.ParseError))]
        public void ParseTest4()
        {
            Complex.CreateFromString("1 +- 2i");
        }

        [Test]
        public void ExpTest()
        {
            Complex c1 = new Complex(1, 3);
            Complex c2 = Complex.Exp (c1);
            Assertion.Assert(c2.ToString(), c2.Abs - Math.Exp(1) < 0.0001 && c2.Arg - 3 < 0.0001);
        }

        [Test]
        public void PowTest()
        {
            Complex c1 = new Complex (0.5, -Math.Sqrt(3) / 2);
            Complex c2 = Complex.Pow (c1, 20);
            Assertion.Assert(c2.ToString(), Math.Abs(c2.Real + 0.5) < 0.0001  && Math.Abs(c2.Imag + Math.Sqrt(3) / 2) < 0.0001);
        }

        public static void Main ()
        {
            ComplexTest ct = new ComplexTest();
            //ct.RadicalTest();

            ct.ParseTest();
        }
    }
}


Хм, большое сообщение получилось. Может не стоило так исходники писать?
... << RSDN@Home 1.1.3 stable >>
Софт, исходники и фото
Re[2]: SRC: Комплексные числа на C#
От: migel  
Дата: 07.05.04 09:47
Оценка: 15 (1)
Здравствуйте, Jenyay, Вы писали:

J>Вот, довел до ума класс по советам vdimas Re[3]: SRC: Комплексные числа на C#
Автор: vdimas
Дата: 23.04.04
.


J>Complex.cs:

J>
J>using System;

J>namespace Jenyay
J>{
J>    /// <summary>
J>    /// Класс комплексных чисел
J>    /// </summary>
J>    public struct Complex
J>    {
J>        /// <summary>
J>        /// Бросаемое исключение при неудачном парсинге строки
J>        /// </summary>

А почему бы не бросать стандартное исключение?FormatException ??

J>        public class ParseError : System.Exception
J>        {
// skip
J>        }

J>        }

J>        private double m_real;
J>        private double m_imag;

J>        #region Конструкторы

// skip
J>        #endregion

// может проще писать Re Im (вроде в мат. литературе часто используется)??
J>        public double Real
// skip

J>        public double Imag
// skip
J>        /// <summary>
J>        /// Создает переменную типа Complex из строки
J>        /// </summary>
J>        /// <param name="str">Строка, по которой создаем переменную</param>
J>        /// <returns>Полученную переменную или бросает исключение в случае неудачи</returns>
// может стоит назвать Parse - по аналогии с офицерским ботинком  ;) ????  
J>        public static Complex CreateFromString(string str)
J>        {
J>            /* Это лучше вынести в комментарий к методу
J>             Возможные варианты строк:
J>             1+5i
J>             1 + 5i
J>             +1 + 5i
J>             -1 - 5i
J>             -5
J>             -6i
J>             +6i
J>             i
J>             1+i
J>             -i
J>            */
// skip
J>        }

// skip
J>}
J>
... << RSDN@Home 1.1.3 stable >>
Re[3]: SRC: Комплексные числа на C#
От: Jenyay http://jenyay.net
Дата: 07.05.04 14:13
Оценка:
Здравствуйте, migel, Вы писали:

M>Здравствуйте, Jenyay, Вы писали:


M>А почему бы не бросать стандартное исключение?FormatException ??


Не знал, что такое существует.

И за остальное спасибо — подправлю.
... << RSDN@Home 1.1.3 stable >>
Софт, исходники и фото
Re[4]: SRC: Комплексные числа на C#
От: Jenyay http://jenyay.net
Дата: 07.05.04 15:08
Оценка: 6 (1)
Подправил.

Исходники лежат здесь.

Complex.cs:

using System;

namespace Jenyay
{
    /// <summary>
    /// Класс комплексных чисел
    /// </summary>
    public struct Complex
    {
        /// <summary>
        /// Бросаемое исключение при неудачном парсинге строки
        /// </summary>
        private double m_real;
        private double m_imag;

        #region Конструкторы

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

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

        public Complex (Complex x)
        {
            m_real = x.Re;
            m_imag = x.Im;
        }

        public Complex (Polar x)
        {
            m_real = x.R * Math.Cos(x.Phi);
            m_imag = x.R * Math.Sin(x.Phi);
        }
        #endregion

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

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

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


        /// <summary>
        /// Аргумент числа в интервале [0; 2* pi)
        /// </summary>
        public double Arg
        {
            get 
            { 
                double res = Math.Atan2(m_imag, m_real);
                if (res < 0)
                {
                    res += Math.PI;
                }
                return res; 
            }
        }

        /// <summary>
        /// Константа 0 + j
        /// </summary>
        public static Complex J
        {
            get
            {
                return new Complex(0, 1);
            }
        }

        /// <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.Re + c2.Re, c1.Im + c2.Im);
        }

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

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


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

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

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


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

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

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


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

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

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

        #region Операторы сравнения
        public static bool operator == (Complex c1, Complex c2)
        {
            return c1.Re == c2.Re && c1.Im == c2.Im;
        }

        public static bool operator == (Complex c, double x)
        {
            return c.Re == x && c.Im == 0;
        }

        public static bool operator == (double d, Complex c)
        {
            return c == d;
        }

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

        public static bool operator != (Complex c, double x)
        {
            return !(c == x);
        }

        public static bool operator != (double x, Complex c)
        {
            return !(c == x);
        }

        public override bool Equals(object obj)
        {
            if (obj == null || obj.GetType() != this.GetType())
            {
                return false;
            }

            return this == (Complex)obj;
        }
        #endregion

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

        public Polar Polar
        {
            get
            {
                return new Polar(this);
            }
            set
            {
                m_real = value.R * Math.Cos(value.Phi);
                m_imag = value.R * Math.Sin(value.Phi);
            }
        }

        /// <summary>
        /// Считает квадратный корень
        /// </summary>
        /// <param name="c">Число, из которого считают корень</param>
        /// <returns></returns>
        public static Complex Sqrt (Complex c)
        {
            double abs = Math.Sqrt(c.Abs);
            return new Complex (abs * Math.Cos(c.Arg / 2), abs * Math.Sin(c.Arg / 2));
        }

        public static Complex Sqrt(double x)
        {
            // По идее, если x < 0, то рез-т должен быть +- a*i, но все-таки возвращаем только с +.
            return x >= 0 ? new Complex(Math.Sqrt(x)) : new Complex (0, Math.Sqrt(-x));
        }

        /// <summary>
        /// Считает все корни степени n (n штук)
        /// </summary>
        /// <param name="c">Число, из которого извлекаем корень</param>
        /// <param name="n">Степень корня</param>
        /// <returns>Массив с результатами</returns>
        public static Complex[] Radical (Complex c, int n)
        {
            Complex[] res = new Complex[n];

            double abs = Math.Pow(c.Abs, 1.0 / n);

            // Начальный угол
            double Phi0 = c.Arg / n;

            // Шаг по углу
            double dPhi = 2 * Math.PI / n;

            for (int i = 0; i < n; ++i)
            {
                double CurrPhi = Phi0 + i * dPhi;
                res[i] = new Complex(abs * Math.Cos(CurrPhi), abs * Math.Sin(CurrPhi));
            }

            return res;
        }


        /// <summary>
        /// Создает переменную типа Complex из строки
        /// </summary>
        /// <param name="str">Строка, по которой создаем переменную</param>
        /// <remarks>
        ///     Возможные варианты строк:
        ///     1+5i
        ///     1 + 5i
        ///     +1 + 5i
        ///     -1 - 5i
        ///     -5
        ///     -6i
        ///     +6i
        ///     i
        ///     1+i
        ///     -i
        /// </remarks>
        /// <returns>Полученную переменную или бросает исключение в случае неудачи</returns>
        public static Complex Parse(string str)
        {
            // В качестве i может быть написано j и может быть любое число пробелов

            // 1. Удаляем все пробелы
            string TempStr = str.Replace(" ", "");

            // 2. Заменяем j на i
            TempStr = TempStr.Replace("j", "i");

            // 3. Находим мнимую часть
            double imag = 0;

            // Если последний символ - i, значит мнимая часть есть
            int pos = TempStr.Length - 1;
            if (TempStr[TempStr.Length - 1] == 'i')
            {
                string ImagStr = "";

                for (pos--; pos >= 0; --pos)
                {
                    char CurrChar = TempStr[pos];

                    // Если идет число, то просто добавляем символ в начало
                    if (CurrChar >= '0' && CurrChar <= '9')
                    {
                        ImagStr = CurrChar + ImagStr;
                    }
                    else if (CurrChar == '+' || CurrChar == '-')
                    {
                        // Если знак, то добавляем его и обрываем цикл
                        ImagStr = CurrChar + ImagStr;

                        // Если строка теперь состоит из одного знака, то добавим 1
                        if (ImagStr.Length == 1)
                        {
                            ImagStr += "1";
                        }
                        break;
                    }
                    else
                    {
                        // Если что-то другое, значит ошибка
                        throw new FormatException (str);
                    }
                }

                if (ImagStr.Length == 0)
                {
                    imag = 1.0;
                }
                else
                {
                    imag = Convert.ToDouble(ImagStr);
                }
                pos--;
            }

            // 4. Получаем реальную часть
            double real = 0;
            // Если еще может быть реальная часть
            if (pos >= 0)
            {

                // Если дальше идет число
                if (TempStr[pos] >= '0' && TempStr[pos] <= '9')
                {
                    string RealStr = TempStr[pos].ToString();

                    for (pos--; pos >= 0; --pos)
                    {
                        char CurrChar = TempStr[pos];

                        // Если идет число, то просто добавляем символ в начало
                        if (CurrChar >= '0' && CurrChar <= '9')
                        {
                            RealStr = CurrChar + RealStr;
                        }
                        else if (CurrChar == '+' || CurrChar == '-')
                        {
                            // Если знак, то добавляем его и обрываем цикл
                            RealStr = CurrChar + RealStr;
                            break;
                        }
                        else
                        {
                            // Если что-то другое, значит ошибка
                            throw new FormatException (str);
                        }
                    }

                    real = Convert.ToDouble(RealStr);
                }
                else
                {
                    throw new FormatException (str);
                }
            }

            return new Complex(real, imag);
        }

        /// <summary>
        /// Вычисление экспоненты комплексного числа
        /// </summary>
        /// <param name="c">Число от которого ищут экспоненту</param>
        public static Complex Exp (Complex c)
        {
            return new Complex (new Polar(Math.Exp(c.Re), c.Im) );
        }


        /// <summary>
        /// Возведение комплексного числа в степень
        /// </summary>
        /// <param name="n">Степень в которую возводим число</param>
        public static Complex Pow (Complex c, int n)
        {
            double NewArg = c.Arg * n;
            double NewAbs = 1;
            for (int i = 0; i < n; ++i)
            {
                NewAbs *= c.Abs;
            }

            return new Complex (new Polar (NewAbs, NewArg) );
        }
    }
}


Тесты:

using System;
using NUnit.Framework;

using Jenyay;

namespace ComplexTest
{
    /// <summary>
    /// Класс для теста полярного представления комплексных чисел
    /// </summary>
    [TestFixture]
    public class PolarTest
    {
        [Test]
        public void InitTest()
        {
            Polar p1 = new Polar(1.0, 2.0);
            Assertion.Assert (p1.R == 1.0 && p1.Phi == 2.0);

            Polar p2 = new Polar(3.0);
            Assertion.Assert (p2.R == 3.0 && p2.Phi == 0.0);

            Complex c1 = new Complex (2.0, 2.0);
            Polar p3 = new Polar (c1);
            Assertion.Assert(p3.ToString(), p3.R == Math.Sqrt(8.0) && p3.Phi - Math.PI / 4.0 < 0.0001);

            Complex c3 =  new Complex (p3);
            Assertion.Assert(c3.ToString(), c3.Re - 2.0 < 0.000001 && c3.Im - 2.0 < 0.000001);
        }

        [Test]
        public void OperatorsTest()
        {
            Complex c1  = new Complex (1, 2);
            Complex c2 = new Complex (2, 3);

            Polar p1 = new Polar (c2);

            Complex c3 = c1 + p1;
            Assertion.Assert(c3.ToString(), c3.Re == 3.0 && c3.Im == 5.0);

            Complex c4 = p1 + c1;
            Assertion.Assert(c4.ToString(), c4.Re == 3.0 && c4.Im == 5.0);


            Complex c5 = c1 - p1;
            Assertion.Assert(c5.ToString(), c5 == c1 - c2);

            Complex c6 = p1 - c1;
            Assertion.Assert(c6.ToString(), c6 == c2 - c1);


            Complex c7 = c1 * p1;
            Assertion.Assert(c7.ToString(), c7 == c1 * c2);

            Complex c8 = p1 * c1;
            Assertion.Assert(c8.ToString(), c8 == c2 * c1);


            Complex c9 = c1 / p1;
            Assertion.Assert(c9.ToString(), c9 == c1 / c2);

            Complex c10 = p1 / c1;
            Assertion.Assert(c10.ToString(), c10 == c2 / c1);

            
            Complex c11 = new Complex(2, 2);
            Assertion.Assert (((Polar)c11).R == Math.Sqrt(8.0) && 
                ((Polar)c11).Phi - Math.PI / 4.0 < 0.0001);

            Polar p2 = new Polar(c11);
            Assertion.Assert(((Complex)p2).Abs == p2.R);
        }
    }
    

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

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

            Complex c2 = new Complex(2.1);
            Assertion.Assert(c2.Re == 2.1 && c2.Im == 0.0);

            Complex c3 = new Complex (3.3, 4.4);
            Assertion.Assert(c3.Re == 3.3 && c3.Im == 4.4);

            Complex c4 = new Complex (c3);
            Assertion.Assert(c4.Re == 3.3 && c4.Im == 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 = c2;
            Assertion.Assert(c1.Re == c2.Re && c1.Im == c2.Im);
            Assertion.Assert(c1 == c2);
            Assertion.Assert (c1 != c3);

            c1.Re = 5.0;
            c1.Im = 6.0;
            Assertion.Assert(c1.Re != c2.Re && c1.Im != c2.Im);
            Assertion.Assert(c1 != c2);
            Assertion.Assert (c1 == c3);

            Complex c4 = new Complex (1, 0);
            double d = 1;
            Assertion.Assert(c4 == d);
            Assertion.Assert(d == c4);

            Assertion.Assert(c3 != d);
            Assertion.Assert(d != c3);
        }

        [Test]
        public void MiscTest()
        {
            // Проверка модуля
            Complex c1 = new Complex (1.0, 5.0);
            Assertion.Assert(c1.ToString(), c1.Abs == Math.Sqrt(26.0) && c1.Re == 1.0 && c1.Im == 5.0);

            // Комплексно-сопряженные числа
            Complex c2 = c1.GetConjugate();
            Assertion.Assert(c2.ToString(), c2.Re == 1.0 && c2.Im == -5.0 &&
                c1.Re == 1.0 && c1.Im == 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.Re == 0.1 && c3.Im == 5.7);

            // Проверка аргумента
            double arg = c1.Arg;
            Assertion.Assert (arg.ToString(), arg - 1.373 < 0.001);

            Complex c8 = new Complex (1, 1);
            Assertion.Assert (c8.Arg.ToString(), c8.Arg - 0.785 < 0.001);

            Complex c9 = new Complex (-1, 1);
            Assertion.Assert (c9.Arg.ToString(), c9.Arg - 2.356 < 0.001);

            Complex c10 = new Complex (-1, -1);
            Assertion.Assert (c10.Arg.ToString(), c10.Arg - 3.927 < 0.001);

            Complex c11 = new Complex (1, -1);
            Assertion.Assert (c11.Arg.ToString(), c11.Arg - 5.498 < 0.001);

            // Проверка квадратного корня
            Complex c4 = new Complex(1, 4);
            Complex c5 = Complex.Sqrt(c4);
            Assertion.Assert(c5.ToString(), c5.Re - 1.6 < 0.01 && c5.Im - 1.25 < 0.01);

            Complex c6 = Complex.Sqrt(-9);
            Assertion.Assert(c6.ToString(), c6.Re == 0 && c6.Im == 3);

            Complex c7 = Complex.Sqrt(4);
            Assertion.Assert(c7.ToString(), c7.Re == 2 && c7.Im == 0);

            // Проверка константы j
            Complex c12 = Complex.J;
            Assertion.Assert (c12.ToString(), c12.Re == 0 && c12.Im == 1);

            Complex c13 = new Complex(2, 3);
            Complex c14 = c13 + Complex.J;
            Assertion.Assert(c14.ToString(), c14.Re == 2 && c14.Im == 4);
        }

        [Test]
        public void RadicalTest()
        {
            Complex c1 = new Complex(-8, 8 * Math.Sqrt(3));
            Complex[] CArr = Complex.Radical(c1, 4);
            Assertion.Assert (CArr.Length == 4);
            Assertion.Assert (CArr[0].ToString(), Math.Abs(CArr[0].Re - Math.Sqrt(3)) < 0.0001 && CArr[0].Im == 1);
            Assertion.Assert (CArr[1].ToString(), Math.Abs(CArr[1].Re + 1) < 0.001 && Math.Abs(CArr[1].Im - Math.Sqrt(3)) < 0.0001);
            Assertion.Assert(CArr[2].ToString(), Math.Abs(CArr[2].Re + Math.Sqrt(3)) < 0.0001 && Math.Abs(CArr[2].Im + 1) < 0.0001);
            Assertion.Assert(CArr[3].ToString(), Math.Abs(CArr[3].Re - 1) < 0.0001 && Math.Abs(CArr[3].Im + Math.Sqrt(3)) < 0.0001);
        }

        [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.Re == 6.0 && c3.Im == 9.0);

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

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

            c1 += 5;
            Assertion.Assert(c1.ToString(), c1.Re == 6.0 && c1.Im == 3.0);

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

            c1 += c2;
            Assertion.Assert(c1.ToString(), c1.Re == 8.2 && c1.Im == 13.7);

            c1 += 10;
            Assertion.Assert (c1.ToString(), c1.Re == 18.2 && c1.Im == 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.Re == -4.0 && c3.Im == -3.0);

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

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

            c1 -= c3;
            Assertion.Assert(c1.ToString(), c1.Re == -3 && c1.Im == 6);

            c1 -= -13;
            Assertion.Assert(c1.ToString(), c1.Re == 10 && c1.Im == 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.Re == 7 && c3.Im == -4);
            Assertion.Assert(c3 == c4);

            c2 = c1 * 3;
            Assertion.Assert(c2.Re == 3 && c2.Im == -6);

            c2 = -5 * c1;
            Assertion.Assert(c2.Re == -5 && c2.Im == 10);

            c2 *= c1;
            Assertion.Assert(c2.Re == 15 && c2.Im == 20);

            c2 *= 0.2;
            Assertion.Assert (c2.ToString(), c2.Re == 3 && c2.Im == 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.Re == 1 && c3.Im == -2);

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

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

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

            c2.Re = 1;
            c2.Im = 3;
            c1 /= c2;
            Assertion.Assert(c1.ToString(), c1.Re == -2.5 && c1.Im == -2.5);
        }

        [Test]
        public void ParseTest()
        {
            Complex c1 = Complex.Parse("5 + 6i");
            Assertion.Assert(c1.ToString(), c1.Re == 5 && c1.Im == 6);

            Complex c2 = Complex.Parse("65 - 61j");
            Assertion.Assert(c2.ToString(), c2.Re == 65 && c2.Im == -61);

            Complex c3 = Complex.Parse("+100 - 02j");
            Assertion.Assert(c3.ToString(), c3.Re == 100 && c3.Im == -2);

            Complex c4 = Complex.Parse("2 + j");
            Assertion.Assert(c4.ToString(), c4.Re == 2 && c4.Im == 1);

            Complex c5 = Complex.Parse("3 - j");
            Assertion.Assert(c5.ToString(), c5.Re == 3 && c5.Im == -1);

            Complex c6 = Complex.Parse("5");
            Assertion.Assert(c6.ToString(), c6.Re == 5 && c6.Im == 0);

            Complex c7 = Complex.Parse("-78");
            Assertion.Assert(c7.ToString(), c7.Re == -78 && c7.Im == 0);

            Complex c8 = Complex.Parse("j");
            Assertion.Assert(c8.ToString(), c8.Re == 0 && c8.Im == 1);

            Complex c9 = Complex.Parse("-j");
            Assertion.Assert(c9.ToString(), c9.Re == 0 && c9.Im == -1);

            Complex c10 = Complex.Parse("5j");
            Assertion.Assert(c10.ToString(), c10.Re == 0 && c10.Im == 5);

            Complex c11 = Complex.Parse("11j");
            Assertion.Assert(c11.ToString(), c11.Re == 0 && c11.Im == 11);

            Complex c12 = Complex.Parse("-1j");
            Assertion.Assert(c12.ToString(), c12.Re == 0 && c12.Im == -1);

            Complex c13 = Complex.Parse("-23j");
            Assertion.Assert(c13.ToString(), c13.Re == 0 && c13.Im == -23);
        }

        [Test, ExpectedException(typeof (FormatException))]
        public void ParseTest2()
        {
            Complex.Parse("dsfsd34");
        }

        [Test, ExpectedException(typeof (FormatException))]
        public void ParseTest3()
        {
            Complex.Parse("+");
        }

        [Test, ExpectedException(typeof (FormatException))]
        public void ParseTest4()
        {
            Complex.Parse("1 +- 2i");
        }

        [Test]
        public void ExpTest()
        {
            Complex c1 = new Complex(1, 3);
            Complex c2 = Complex.Exp (c1);
            Assertion.Assert(c2.ToString(), c2.Abs - Math.Exp(1) < 0.0001 && c2.Arg - 3 < 0.0001);
        }

        [Test]
        public void PowTest()
        {
            Complex c1 = new Complex (0.5, -Math.Sqrt(3) / 2);
            Complex c2 = Complex.Pow (c1, 20);
            Assertion.Assert(c2.ToString(), Math.Abs(c2.Re + 0.5) < 0.0001  && Math.Abs(c2.Im + Math.Sqrt(3) / 2) < 0.0001);
        }

        public static void Main ()
        {
            ComplexTest ct = new ComplexTest();
            //ct.RadicalTest();

            ct.ParseTest();
        }
    }
}
... << RSDN@Home 1.1.3 stable >>
Софт, исходники и фото
Re[5]: SRC: Комплексные числа на C#
От: vdimas Россия  
Дата: 11.05.04 20:01
Оценка: 10 (1)
Здравствуйте, Jenyay, Вы писали:

J>
J>        /// <summary>
J>        /// Константа 0 + j
J>        /// </summary>
private static complex m_j=new Complex(0, 1);
J>        public static Complex J
J>        {
J>            get
J>            {
J>                return m_j;
J>            }
J>        }

// лучше использовать StringBuilder
J>        public override string ToString()


J>        public static bool operator == (Complex c, double x)
J>        {
J>            return c.Re == x && c.Im == 0; // поменять условия местами
J>        }

J>        public static Complex Parse(string str) // над этим еще можно малость можно поработать ;)J>


а вообще — весьма полезный класс
Re[6]: SRC: Комплексные числа на C#
От: Jenyay http://jenyay.net
Дата: 12.05.04 17:59
Оценка:
Здравствуйте, vdimas, Вы писали:

Как будет время постараюсь все подправить. А то уже сессия начинается

V>// лучше использовать StringBuilder

J>> public override string ToString()

Почитаю еще MSDN, но не уверен, что с ним удастся сделать "человеческий" вид, т.е., чтобы было как с обычной записью без лишних нулей и прюсов. Кстати, заметил, что тут еще надо будет сделать, чтобы, если мнимая часть == +-1, то эту единицу перед j не писал.

J>> public static Complex Parse(string str) // над этим еще можно малость можно поработать J>[/c#]


Надо профайлером погонять.

V>а вообще — весьма полезный класс


Спасибо
... << RSDN@Home 1.1.3 stable >>
Софт, исходники и фото
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.