注释
本文提供了此 API 参考文档的补充说明。
复数是包含实数部分和虚数部分的数字。 复数 z 通常以形式 z = x + yi编写,其中 x 和 y 是实数, i 是具有属性 i2 = -1 的虚构单位。 复数的实际部分由 x 表示,复数的虚部由 y 表示。
该 Complex 类型在实例化和操作复数时使用笛卡尔坐标系(真实、虚构)。 复数可以表示为二维坐标系中的点,称为复杂平面。 复数的实际部分位于 x 轴(水平轴)上,虚部位于 y 轴(垂直轴) 上。
使用极坐标系统还可以根据复杂平面中的任何点的绝对值来表示。 在极坐标中,一个点由两个数字表示:
- 其数量级,它是与原点(即 0,0,或 x 轴和 y 轴相交的点)的距离。
- 其相位是从原点到该点绘制的线条与实轴之间的角度。
实例化复数
可以通过以下方法之一将值分配给复数:
将两个 Double 值传递给其构造函数。 第一个值表示复数的实际部分,第二个值表示其虚部。 这些值表示二维笛卡尔坐标系中复数的位置。
通过调用静态(
Shared在 Visual Basic 中) Complex.FromPolarCoordinates 方法,从其极坐标创建复数。通过将Byte、SByte、Int16、UInt16、Int32、UInt32、Int64、UInt64值分配给Complex对象来赋予Single值。 该值将成为复数的实际部分,其虚部等于 0。
通过在 C# 中将 Decimal 或 BigInteger 值转换为 Complex 对象,或在 Visual Basic 中进行转换。 该值将成为复数的实际部分,其虚部等于 0。
通过将方法或运算符 Complex 返回的复数分配给对象。 例如,是一个静态方法, Complex.Add 它返回一个复数,该复数是两个复数的总和,运算符 Complex.Addition 添加两个复数并返回结果。
以下示例演示了将值分配给复数的五种方法中的每一种。
using System;
using System.Numerics;
public class CreateEx
{
public static void Run()
{
// Create a complex number by calling its class constructor.
Complex c1 = new Complex(12, 6);
Console.WriteLine(c1);
// Assign a Double to a complex number.
Complex c2 = 3.14;
Console.WriteLine(c2);
// Cast a Decimal to a complex number.
Complex c3 = (Complex)12.3m;
Console.WriteLine(c3);
// Assign the return value of a method to a Complex variable.
Complex c4 = Complex.Pow(Complex.One, -1);
Console.WriteLine(c4);
// Assign the value returned by an operator to a Complex variable.
Complex c5 = Complex.One + Complex.One;
Console.WriteLine(c5);
// Instantiate a complex number from its polar coordinates.
Complex c6 = Complex.FromPolarCoordinates(10, .524);
Console.WriteLine(c6);
}
}
// The example displays the following output:
// (12, 6)
// (3.14, 0)
// (12.3, 0)
// (1, 0)
// (2, 0)
// (8.65824721882145, 5.00347430269914)
Imports System.Numerics
Module Example
Public Sub Run()
' Create a complex number by calling its class constructor.
Dim c1 As New Complex(12, 6)
Console.WriteLine(c1)
' Assign a Double to a complex number.
Dim c2 As Complex = 3.14
Console.WriteLine(c2)
' Cast a Decimal to a complex number.
Dim c3 As Complex = CType(12.3d, Complex)
Console.WriteLine(c3)
' Assign the return value of a method to a Complex variable.
Dim c4 As Complex = Complex.Pow(Complex.One, -1)
Console.WriteLine(c4)
' Assign the value returned by an operator to a Complex variable.
Dim c5 As Complex = Complex.One + Complex.One
Console.WriteLine(c5)
' Instantiate a complex number from its polar coordinates.
Dim c6 As Complex = Complex.FromPolarCoordinates(10, .524)
Console.WriteLine(c6)
End Sub
End Module
' The example displays the following output:
' (12, 6)
' (3.14, 0)
' (12.3000001907349, 0)
' (1, 0)
' (2, 0)
' (8.65824721882145, 5.00347430269914)
包含复数的操作
Complex.NET 中的结构包括提供以下功能的成员:
- 用于比较两个复数的方法,以确定它们是否相等。
- 用于对复数执行算术运算的运算符。 Complex 运算符使你能够使用复数执行加法、减法、乘法、除法和一元求反。
- 对复数执行其他数值运算的方法。 除了四个基本算术运算外,还可以将复数提升为指定幂,查找复数的平方根,并获取复数的绝对值。
- 对复数执行三角运算的方法。 例如,可以计算由复数表示的角度的正切值。
请注意,由于Real和Imaginary属性是只读的,这意味着您无法修改现有Complex对象的值。 对Complex数字进行运算的所有方法,如果其返回值类型是Complex,则返回一个新的Complex数字。
精度和复数
复数的实数和虚部由两个双精度浮点值表示。 这意味着 Complex 值(如双精度浮点值)可能会因数值运算而失去精度。 这意味着,即使两 Complex 个值之间的差异是由于精度损失,两个值的相等性严格比较也可能失败。 有关详细信息,请参阅 Double。
例如,对一个数字的对数进行指数运算应返回该数字本身。 但是,在某些情况下,浮点值的精度损失可能会导致两个值之间的细微差异,如以下示例所示。
Complex value = new Complex(Double.MinValue / 2, Double.MinValue / 2);
Complex value2 = Complex.Exp(Complex.Log(value));
Console.WriteLine($"{value} \n{value2} \nEqual: {value == value2}");
// The example displays the following output:
// (-8.98846567431158E+307, -8.98846567431158E+307)
// (-8.98846567431161E+307, -8.98846567431161E+307)
// Equal: False
Dim value As New Complex(Double.MinValue / 2, Double.MinValue / 2)
Dim value2 As Complex = Complex.Exp(Complex.Log(value))
Console.WriteLine("{0} {3}{1} {3}Equal: {2}", value, value2,
value = value2,
vbCrLf)
' The example displays the following output:
' (-8.98846567431158E+307, -8.98846567431158E+307)
' (-8.98846567431161E+307, -8.98846567431161E+307)
' Equal: False
同样,下面的示例计算数字 Complex 的平方根,在 32 位和 IA64 版本的 .NET 上生成略有不同的结果。
Complex minusOne = new Complex(-1, 0);
Console.WriteLine(Complex.Sqrt(minusOne));
// The example displays the following output:
// (6.12303176911189E-17, 1) on 32-bit systems.
// (6.12323399573677E-17,1) on IA64 systems.
Dim minusOne As New Complex(-1, 0)
Console.WriteLine(Complex.Sqrt(minusOne))
' The example displays the following output:
' (6.12303176911189E-17, 1) on 32-bit systems.
' (6.12323399573677E-17,1) on IA64 systems.
无穷大和 NaN
复数的实数和虚部由 Double 值表示。 除了从 Double.MinValue 到 Double.MaxValue,复数的实部或虚部还可以取值 Double.PositiveInfinity,Double.NegativeInfinity,或 Double.NaN。 Double.PositiveInfinity、Double.NegativeInfinity和Double.NaN在任何算术或三角运算中都会传播。
在下面的示例中,除以 Zero 产生一个复数,其实数和虚数部分均为 Double.NaN。 因此,使用此值进行乘法也会生成一个其实数部分和虚数部分为 Double.NaN 的复数。 同样,执行溢出范围的Double乘法会生成一个复数,其实部是Double.NaN,其虚部是Double.PositiveInfinity。 随后,使用此复数执行除法将返回一个复数,其实部是Double.NaN,虚部是Double.PositiveInfinity。
using System;
using System.Numerics;
public class NaNEx
{
public static void Run()
{
Complex c1 = new Complex(Double.MaxValue / 2, Double.MaxValue / 2);
Complex c2 = c1 / Complex.Zero;
Console.WriteLine(c2.ToString());
c2 = c2 * new Complex(1.5, 1.5);
Console.WriteLine(c2.ToString());
Console.WriteLine();
Complex c3 = c1 * new Complex(2.5, 3.5);
Console.WriteLine(c3.ToString());
c3 = c3 + new Complex(Double.MinValue / 2, Double.MaxValue / 2);
Console.WriteLine(c3);
}
}
// The example displays the following output:
// (NaN, NaN)
// (NaN, NaN)
// (NaN, Infinity)
// (NaN, Infinity)
Imports System.Numerics
Module Example4
Public Sub Run()
Dim c1 As Complex = New Complex(Double.MaxValue / 2, Double.MaxValue / 2)
Dim c2 As Complex = c1 / Complex.Zero
Console.WriteLine(c2.ToString())
c2 = c2 * New Complex(1.5, 1.5)
Console.WriteLine(c2.ToString())
Console.WriteLine()
Dim c3 As Complex = c1 * New Complex(2.5, 3.5)
Console.WriteLine(c3.ToString())
c3 = c3 + New Complex(Double.MinValue / 2, Double.MaxValue / 2)
Console.WriteLine(c3)
End Sub
End Module
' The example displays the following output:
' (NaN, NaN)
' (NaN, NaN)
'
' (NaN, Infinity)
' (NaN, Infinity)
对于复数的数学运算,如果无效或者溢出了 Double 数据类型的范围,程序不会抛出异常。 相反,它们在以下条件下返回Double.PositiveInfinity、Double.NegativeInfinity或Double.NaN:
- 正数除以零返回 Double.PositiveInfinity。
- 溢出数据类型上限 Double 的任何操作都 Double.PositiveInfinity返回。
- 负数除以零返回 Double.NegativeInfinity。
- 溢出数据类型下限 Double 的任何操作都 Double.NegativeInfinity返回。
- 零除以零返回 Double.NaN。
- 对操作数值为Double.PositiveInfinity、Double.NegativeInfinity或Double.NaN的任何操作,所返回的结果为Double.PositiveInfinity、Double.NegativeInfinity或Double.NaN,具体取决于特定操作。
请注意,这适用于方法执行的任何中间计算。 例如,new Complex(9e308, 9e308) and new Complex(2.5, 3.5) 乘法使用公式 (ac - bd) + (ad + bc)i。 乘法结果的实际组件计算表达式 9e308 2.5 - 9e308 3.5。 此表达式中的每个中间乘法返回Double.PositiveInfinity,试图从Double.PositiveInfinity中减去Double.PositiveInfinity返回Double.NaN。
设置复数的格式
默认情况下,复数的字符串表示形式为<实部; + 虚部>,其中实部和虚部是构成复数实部和虚部分量的值的字符串表示形式。 此方法的某些 ToString 重载允许自定义这些 Double 值的字符串表示形式,以体现特定文化的格式约定,或者以标准或自定义的数字格式字符串定义的特定格式显示。 (有关详细信息,请参阅 标准数值格式字符串 和 自定义数字格式字符串。)
表示复数的字符串表示方式之一采用形式 a + bi,其中 a 是复数的实部,b 是复数的虚部。 在电气工程中,复数最常表示为 a + bj。 返回复数的字符串表示形式可以采用两种形式之一。 为此,请通过实现 ICustomFormatter 和 IFormatProvider 接口来定义自定义格式提供程序,然后调用 String.Format(IFormatProvider, String, Object[]) 该方法。
以下示例定义一个 ComplexFormatter 类,该类以任 a + bi 一或 a + bj二者的形式将复数表示为字符串。
using System;
using System.Numerics;
public class ComplexFormatter : IFormatProvider, ICustomFormatter
{
public object GetFormat(Type formatType)
{
if (formatType == typeof(ICustomFormatter))
return this;
else
return null;
}
public string Format(string format, object arg,
IFormatProvider provider)
{
if (arg is Complex c1)
{
// Check if the format string has a precision specifier.
int precision;
string fmtString = string.Empty;
if (format.Length > 1)
{
try
{
precision = int.Parse(format.Substring(1));
}
catch (FormatException)
{
precision = 0;
}
fmtString = "N" + precision.ToString();
}
if (format.Substring(0, 1).Equals("I", StringComparison.OrdinalIgnoreCase))
{
// Determine the sign to display.
char sign = c1.Imaginary < 0 ? '-' : '+';
// Display the determined sign and the absolute value of the imaginary part.
return c1.Real.ToString(fmtString) + " " + sign + " " + Math.Abs(c1.Imaginary).ToString(fmtString) + "i";
}
else if (format.Substring(0, 1).Equals("J", StringComparison.OrdinalIgnoreCase))
{
// Determine the sign to display.
char sign = c1.Imaginary < 0 ? '-' : '+';
// Display the determined sign and the absolute value of the imaginary part.
return c1.Real.ToString(fmtString) + " " + sign + " " + Math.Abs(c1.Imaginary).ToString(fmtString) + "j";
}
else
return c1.ToString(format, provider);
}
else
{
if (arg is IFormattable formattable)
return formattable.ToString(format, provider);
else if (arg != null)
return arg.ToString();
else
return string.Empty;
}
}
}
Imports System.Numerics
Public Class ComplexFormatter
Implements IFormatProvider, ICustomFormatter
Public Function GetFormat(formatType As Type) As Object _
Implements IFormatProvider.GetFormat
If formatType Is GetType(ICustomFormatter) Then
Return Me
Else
Return Nothing
End If
End Function
Public Function Format(fmt As String, arg As Object,
provider As IFormatProvider) As String _
Implements ICustomFormatter.Format
If TypeOf arg Is Complex Then
Dim c1 As Complex = DirectCast(arg, Complex)
' Check if the format string has a precision specifier.
Dim precision As Integer
Dim fmtString As String = String.Empty
If fmt.Length > 1 Then
Try
precision = Integer.Parse(fmt.Substring(1))
Catch e As FormatException
precision = 0
End Try
fmtString = "N" + precision.ToString()
End If
' Determine the sign to display.
Dim sign As Char = If(c1.Imaginary < 0.0, "-"c, "+"c)
' Display the determined sign and the absolute value of the imaginary part.
If fmt.Substring(0, 1).Equals("I", StringComparison.OrdinalIgnoreCase) Then
Return c1.Real.ToString(fmtString) + " " + sign + " " + Math.Abs(c1.Imaginary).ToString(fmtString) + "i"
ElseIf fmt.Substring(0, 1).Equals("J", StringComparison.OrdinalIgnoreCase) Then
Return c1.Real.ToString(fmtString) + " " + sign + " " + Math.Abs(c1.Imaginary).ToString(fmtString) + "j"
Else
Return c1.ToString(fmt, provider)
End If
Else
If TypeOf arg Is IFormattable Then
Return DirectCast(arg, IFormattable).ToString(fmt, provider)
ElseIf arg IsNot Nothing Then
Return arg.ToString()
Else
Return String.Empty
End If
End If
End Function
End Class
下面的示例随后使用此自定义格式化程序显示复数的字符串表示形式。
public class CustomFormatEx
{
public static void Run()
{
Complex c1 = new(12.1, 15.4);
Console.WriteLine($"Formatting with ToString: {c1}");
Console.WriteLine($"Formatting with ToString(format): {c1:N2}");
Console.WriteLine($"Custom formatting with I0:\t" +
$" {string.Format(new ComplexFormatter(), "{0:I0}", c1)}");
Console.WriteLine($"Custom formatting with J3:\t" +
$" {string.Format(new ComplexFormatter(), "{0:J3}", c1)}");
}
}
// The example displays the following output:
// Formatting with ToString(): <12.1; 15.4>
// Formatting with ToString(format): <12.10; 15.40>
// Custom formatting with I0: 12 + 15i
// Custom formatting with J3: 12.100 + 15.400j
Module Example2
Public Sub Run()
Dim c1 As New Complex(12.1, 15.4)
Console.WriteLine($"Formatting with ToString(): {c1}")
Console.WriteLine($"Formatting with ToString(format): {c1:N2}")
Console.WriteLine($"Custom formatting with I0: " +
$"{String.Format(New ComplexFormatter(), "{0:I0}", c1)}")
Console.WriteLine($"Custom formatting with J3: " +
$"{String.Format(New ComplexFormatter(), "{0:J3}", c1)}")
End Sub
End Module
' The example displays the following output:
' Formatting with ToString(): <12.1; 15.4>
' Formatting with ToString(format): <12.10; 15.40>
' Custom formatting with I0: 12 + 15i
' Custom formatting with J3: 12.100 + 15.400j