C# 中的复数
Complex numbers in c#
我有一个作业要编写复数实现 :-
Complex c = new Complex(1.2,2.0)
写入属性 real 和 Imaginary 以获得复数的实部和虚部。像这样使用:
double x = c.Real;
编写一个方法将两个复数相加并 return 它们的和。实部是两个实部之和,虚部是两个虚部之和
Complex c = c1.Sum(c2);
写一个方法来计算两个复数的乘积。如果一个数字有分量 x1
和 y1
,第二个数字有分量,x2
和 y2
:
产品实部=x1 *x2 - y1 *y2
;
虚部 = x1 * y2 + x2 *y1
;
所以我知道并且对手动复数非常有信心,例如 4 +5i
其中 5i
是虚数,
我的问题是,我不确定如何让应用程序知道哪个是虚数,除非我在输入时输入一个预定义的虚数。我这样做的那一刻虽然“应用程序”失去了它的价值因为它不是一个复杂的数字,只是一些随机的计算应用程序。基本上我不知道如何继续..谢谢
从你的问题看来,你对复数的构造感到困惑。这是一个帮助您入门的模板。
public class Complex
{
public Complex(double real, double imaginary)
{
}
}
然后从
开始
static void Main(string[] args)
{
Complex c1 = new Complex(1.2,2.0)
Complex c2 = new Complex(1,3.0)
Complex c3 = c1.Sum(c2);
Console.WriteLine(c3.Real);
Console.WriteLine(c3.Imaginary);
}
并开始工作(为初学者输入您喜欢的任何数字)
"I'm not sure how to get the app to know which one is imaginary" -- 这是一种方法:
Console.WriteLine("Input the real part of the complex number:");
var real = double.Parse(Console.ReadLine());
Console.WriteLine("Input the imaginary part of the complex number:");
var imaginary = double.Parse(Console.ReadLine());
var complexNumber = new Complex(real, imaginary);
什么是复数?好吧,它是一个包含 real 部分和 imaginary 部分的数字。虚部本身就是一个实数乘以这个奇怪的虚数常数 i 使得 i * i = -1
。没有什么比它更多的了,所以就这样实现吧。为什么这会使您的代码失去任何价值?
public struct Complex
{
public static readonly ImaginaryOne = new Complex(0, 1);
public doube Real { get; }
public double Imaginary { get; }
public Complex(double real, double imaginary)
{
Real = real;
Imaginary = imaginary;
}
}
剩下的只是样板...
由于不久前有人提出了这个问题,但我相信还有其他人对此主题感兴趣,所以我决定 post 我最近在 C# 中实现的复数实现。
因为复数是值类型,所以我使用结构而不是 class(在这种情况下结构更快,这是我在编写的一个简单应用程序的帮助下发现的 [=66= ... =]、<
和 >
将与平方数进行比较,而 ==
和 !=
将与相等进行比较。
我用的是双精度,因为分形图形等对精度要求很高。但如果单精度足以满足您的应用需求,您也可以使用单精度。
请注意,这也需要覆盖 GetHashCode()
和 Equals(object obj)
。我还重载了 ++
和 --
运算符,尽管在复杂的世界中有几种可能的解释方式:increment/decrement 实部和虚部或只是其中之一?
我还创建了元组 (a, bi)
和复数之间的隐式转换,因此您可以轻松地初始化它们,例如:
complex a = (1, 2), b = (3, 4); // via tuples (re, im)
您甚至可以像这样解析字符串:
string input = Console.ReadLine();
if (!complex.TryParse(input, out complex c))
Console.WriteLine("Syntax error");
else
Console.WriteLine($"Parsed value for c = {c}");
那么你就可以像
一样简单地使用它们
var w = a - b; Console.WriteLine($"a - b = {w}");
var x = a + b; Console.WriteLine($"a + b = {x}");
var y = a * b; Console.WriteLine($"a * b = {y}");
var z = a / b; Console.WriteLine($"a / b = {z}");
给你输出
a - b = -2 - 2i
a + b = 4 + 6i
a * b = -5 + 10i
a / b = 0.44 + 0.08i
您甚至可以编写一个 for 循环,就像(注意您有 2 个维度!):
for (complex u = (0,0); u <= (5, 5); u.Re++, u.Im++)
{
Console.WriteLine(u);
}
如果也可以进行比较:
if (u==(1, 1)) Console.WriteLine("u == 1+i");
所需的class实现如下:
/// <summary>
/// Complex numbers
/// Written by Matt, 2022
/// </summary>
struct complex
{
public double Re, Im;
public complex(double re, double im)
{
this.Re = re; this.Im = im;
}
public static complex operator ++(complex c) { ++c.Re; ++c.Im; return c; } // not the only way one can implement this
public static complex operator --(complex c) { --c.Re; --c.Im; return c; } // not the only way one can implement this
public static complex operator +(complex a, complex b) => new complex(a.Re + b.Re, a.Im + b.Im);
public static complex operator -(complex a, complex b) => new complex(a.Re - b.Re, a.Im - b.Im);
public static double AmountSqr(complex c) => c.Re * c.Re + c.Im + c.Im;
public static double Amount(complex c) => Math.Sqrt(AmountSqr(c));
/// <summary>Compares the amount of both complex numbers, returns true if |a|<|b|.</summary>
public static bool operator <(complex a, complex b) => AmountSqr(a) < AmountSqr(b);
/// <summary>Compares the amount of both complex numbers, returns true if |a|>|b|.</summary>
public static bool operator >(complex a, complex b) => AmountSqr(a) > AmountSqr(b);
/// <summary>Compares the both complex numbers, returns true if a == b.</summary>
public static bool operator ==(complex a, complex b) => (a.Re == b.Re && a.Im == b.Im);
/// <summary>Compares the both complex numbers, returns true if a != b.</summary>
public static bool operator !=(complex a, complex b) => (a.Re != b.Re || a.Im != b.Im);
// (a+bi)(c+di) = ac-bd + (ad+bc)i
public static complex operator *(complex a, complex b)
=> new complex(a.Re*b.Re-a.Im*b.Im, a.Re*b.Im+a.Im*b.Re);
// (a+bi)/(c+di) = (ac+bd)/(c*c + d*d) + i(bc-ad)/(c*c + d*d)
public static complex operator /(complex a, complex b)
{
var divisor = (b.Re * b.Re + b.Im * b.Im);
return new complex((a.Re*b.Re+a.Im*b.Im)/divisor, (a.Im*b.Re-a.Re*b.Im)/divisor);
}
public static implicit operator complex((double real, double imag) c)
=> new complex(c.real, c.imag); // via tuples (re, im)
public override string ToString()
=> $"{this.Re.ToString().Trim()} {(this.Im < 0 ? "-" : "+")} {Math.Abs(this.Im)}i";
/// <summary>Tries to convert string expressions like "2+3i" or "5-7i" to complex</summary>
public static bool TryParse(string complexNr, out complex result)
{
bool success = false;
result = (0, 0);
try
{
result = Parse(complexNr);
success = true;
} catch {}
return success;
}
/// <summary>Converts string expressions like "2+3i" or "5-7i" to complex</summary>
public static complex Parse(string complexNr)
{
complex result = (0, 0);
try
{
if (complexNr.Contains("-")) complexNr = complexNr.Replace("-", "+-");
var tr = complexNr.Split("+").Select(s => s.Trim()).ToArray();
var realStr = tr[0]; var imagStr = tr[1].TrimEnd('i').Trim();
result = (double.Parse(realStr), double.Parse(imagStr));
}
catch (Exception ex)
{
throw new SyntaxErrorException("Invalid syntax for complex number. Allowed is 'a+bi' or 'a-bi'", ex);
}
return result;
}
public override bool Equals(object obj)
{
return (obj == null) ? false : (this == (complex)obj);
}
public override int GetHashCode()
{
var hash = new HashCode();
hash.Add(this.Re); hash.Add(this.Im);
return hash.ToHashCode();
}
}
参考资料(用于测量“复杂”库性能的 Mandelbrot 算法):
我有一个作业要编写复数实现 :-
Complex c = new Complex(1.2,2.0)
写入属性 real 和 Imaginary 以获得复数的实部和虚部。像这样使用:
double x = c.Real;
编写一个方法将两个复数相加并 return 它们的和。实部是两个实部之和,虚部是两个虚部之和
Complex c = c1.Sum(c2);
写一个方法来计算两个复数的乘积。如果一个数字有分量 x1
和 y1
,第二个数字有分量,x2
和 y2
:
产品实部=x1 *x2 - y1 *y2
;
虚部 = x1 * y2 + x2 *y1
;
所以我知道并且对手动复数非常有信心,例如 4 +5i
其中 5i
是虚数,
我的问题是,我不确定如何让应用程序知道哪个是虚数,除非我在输入时输入一个预定义的虚数。我这样做的那一刻虽然“应用程序”失去了它的价值因为它不是一个复杂的数字,只是一些随机的计算应用程序。基本上我不知道如何继续..谢谢
从你的问题看来,你对复数的构造感到困惑。这是一个帮助您入门的模板。
public class Complex
{
public Complex(double real, double imaginary)
{
}
}
然后从
开始 static void Main(string[] args)
{
Complex c1 = new Complex(1.2,2.0)
Complex c2 = new Complex(1,3.0)
Complex c3 = c1.Sum(c2);
Console.WriteLine(c3.Real);
Console.WriteLine(c3.Imaginary);
}
并开始工作(为初学者输入您喜欢的任何数字)
"I'm not sure how to get the app to know which one is imaginary" -- 这是一种方法:
Console.WriteLine("Input the real part of the complex number:");
var real = double.Parse(Console.ReadLine());
Console.WriteLine("Input the imaginary part of the complex number:");
var imaginary = double.Parse(Console.ReadLine());
var complexNumber = new Complex(real, imaginary);
什么是复数?好吧,它是一个包含 real 部分和 imaginary 部分的数字。虚部本身就是一个实数乘以这个奇怪的虚数常数 i 使得 i * i = -1
。没有什么比它更多的了,所以就这样实现吧。为什么这会使您的代码失去任何价值?
public struct Complex
{
public static readonly ImaginaryOne = new Complex(0, 1);
public doube Real { get; }
public double Imaginary { get; }
public Complex(double real, double imaginary)
{
Real = real;
Imaginary = imaginary;
}
}
剩下的只是样板...
由于不久前有人提出了这个问题,但我相信还有其他人对此主题感兴趣,所以我决定 post 我最近在 C# 中实现的复数实现。
因为复数是值类型,所以我使用结构而不是 class(在这种情况下结构更快,这是我在编写的一个简单应用程序的帮助下发现的 [=66= ... =]、<
和 >
将与平方数进行比较,而 ==
和 !=
将与相等进行比较。
我用的是双精度,因为分形图形等对精度要求很高。但如果单精度足以满足您的应用需求,您也可以使用单精度。
请注意,这也需要覆盖 GetHashCode()
和 Equals(object obj)
。我还重载了 ++
和 --
运算符,尽管在复杂的世界中有几种可能的解释方式:increment/decrement 实部和虚部或只是其中之一?
我还创建了元组 (a, bi)
和复数之间的隐式转换,因此您可以轻松地初始化它们,例如:
complex a = (1, 2), b = (3, 4); // via tuples (re, im)
您甚至可以像这样解析字符串:
string input = Console.ReadLine();
if (!complex.TryParse(input, out complex c))
Console.WriteLine("Syntax error");
else
Console.WriteLine($"Parsed value for c = {c}");
那么你就可以像
一样简单地使用它们var w = a - b; Console.WriteLine($"a - b = {w}");
var x = a + b; Console.WriteLine($"a + b = {x}");
var y = a * b; Console.WriteLine($"a * b = {y}");
var z = a / b; Console.WriteLine($"a / b = {z}");
给你输出
a - b = -2 - 2i
a + b = 4 + 6i
a * b = -5 + 10i
a / b = 0.44 + 0.08i
您甚至可以编写一个 for 循环,就像(注意您有 2 个维度!):
for (complex u = (0,0); u <= (5, 5); u.Re++, u.Im++)
{
Console.WriteLine(u);
}
如果也可以进行比较:
if (u==(1, 1)) Console.WriteLine("u == 1+i");
所需的class实现如下:
/// <summary>
/// Complex numbers
/// Written by Matt, 2022
/// </summary>
struct complex
{
public double Re, Im;
public complex(double re, double im)
{
this.Re = re; this.Im = im;
}
public static complex operator ++(complex c) { ++c.Re; ++c.Im; return c; } // not the only way one can implement this
public static complex operator --(complex c) { --c.Re; --c.Im; return c; } // not the only way one can implement this
public static complex operator +(complex a, complex b) => new complex(a.Re + b.Re, a.Im + b.Im);
public static complex operator -(complex a, complex b) => new complex(a.Re - b.Re, a.Im - b.Im);
public static double AmountSqr(complex c) => c.Re * c.Re + c.Im + c.Im;
public static double Amount(complex c) => Math.Sqrt(AmountSqr(c));
/// <summary>Compares the amount of both complex numbers, returns true if |a|<|b|.</summary>
public static bool operator <(complex a, complex b) => AmountSqr(a) < AmountSqr(b);
/// <summary>Compares the amount of both complex numbers, returns true if |a|>|b|.</summary>
public static bool operator >(complex a, complex b) => AmountSqr(a) > AmountSqr(b);
/// <summary>Compares the both complex numbers, returns true if a == b.</summary>
public static bool operator ==(complex a, complex b) => (a.Re == b.Re && a.Im == b.Im);
/// <summary>Compares the both complex numbers, returns true if a != b.</summary>
public static bool operator !=(complex a, complex b) => (a.Re != b.Re || a.Im != b.Im);
// (a+bi)(c+di) = ac-bd + (ad+bc)i
public static complex operator *(complex a, complex b)
=> new complex(a.Re*b.Re-a.Im*b.Im, a.Re*b.Im+a.Im*b.Re);
// (a+bi)/(c+di) = (ac+bd)/(c*c + d*d) + i(bc-ad)/(c*c + d*d)
public static complex operator /(complex a, complex b)
{
var divisor = (b.Re * b.Re + b.Im * b.Im);
return new complex((a.Re*b.Re+a.Im*b.Im)/divisor, (a.Im*b.Re-a.Re*b.Im)/divisor);
}
public static implicit operator complex((double real, double imag) c)
=> new complex(c.real, c.imag); // via tuples (re, im)
public override string ToString()
=> $"{this.Re.ToString().Trim()} {(this.Im < 0 ? "-" : "+")} {Math.Abs(this.Im)}i";
/// <summary>Tries to convert string expressions like "2+3i" or "5-7i" to complex</summary>
public static bool TryParse(string complexNr, out complex result)
{
bool success = false;
result = (0, 0);
try
{
result = Parse(complexNr);
success = true;
} catch {}
return success;
}
/// <summary>Converts string expressions like "2+3i" or "5-7i" to complex</summary>
public static complex Parse(string complexNr)
{
complex result = (0, 0);
try
{
if (complexNr.Contains("-")) complexNr = complexNr.Replace("-", "+-");
var tr = complexNr.Split("+").Select(s => s.Trim()).ToArray();
var realStr = tr[0]; var imagStr = tr[1].TrimEnd('i').Trim();
result = (double.Parse(realStr), double.Parse(imagStr));
}
catch (Exception ex)
{
throw new SyntaxErrorException("Invalid syntax for complex number. Allowed is 'a+bi' or 'a-bi'", ex);
}
return result;
}
public override bool Equals(object obj)
{
return (obj == null) ? false : (this == (complex)obj);
}
public override int GetHashCode()
{
var hash = new HashCode();
hash.Add(this.Re); hash.Add(this.Im);
return hash.ToHashCode();
}
}
参考资料(用于测量“复杂”库性能的 Mandelbrot 算法):