SRC: Комплексные числа на C#
Ничего точти не делал под .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#
Здравствуйте, vdimas, Вы писали:
V>1. А почему не value type???
Я тоже об этом подумал, когда перечитал статью из какого-то выпуска RSDN про value и ссылочные типы.
Как будет время — подправлю.
... << RSDN@Home 1.1.3 stable >>
Re[2]: SRC: Комплексные числа на C#
Здравствуйте, 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#
Здравствуйте, Jenyay, Вы писали:
J>public override bool Equals(object obj)
{
return this == (Complex)obj;
}
J>
Идологически этот метод exception порождать не должен.
Или я не прав?
Re[2]: SRC: Комплексные числа на C#
Здравствуйте, 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#
Здравствуйте, 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#
Здравствуйте, vdimas, Вы писали:
V>- сделай TypeConverter для Complex, чтобы им можно было пользоваться в качестве полей, доступных для визуального редактирования Property-гридом
А можно про это поподробнее? Что это такое?
А так тогда сюда буду писать по мере продвижения.
... << RSDN@Home 1.1.3 stable >>
Re[2]: SRC: Комплексные числа на C#
Здравствуйте, 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#
Закачал
сюда изменунные классы. Добавил структуру Polar, вычисление корней и исправил баг в определении аргумента.
... << RSDN@Home 1.1.3 stable >>
Re: SRC: Комплексные числа на C#
Вот, довел до ума класс по советам 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#
Здравствуйте, 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#
Здравствуйте, migel, Вы писали:
M>Здравствуйте, Jenyay, Вы писали:
M>А почему бы не бросать стандартное исключение?FormatException ??
Не знал, что такое существует.
И за остальное спасибо — подправлю.
... << RSDN@Home 1.1.3 stable >>
Re[4]: SRC: Комплексные числа на C#
Подправил.
Исходники лежат
здесь .
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#
Здравствуйте, 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#
Здравствуйте, 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 >>
Пока на собственное сообщение не было ответов, его можно удалить.
Удалить