System.Numerics.Complex 结构

本文提供了此 API 参考文档的补充说明。

复数是包含实数部分和虚数部分的数字。 复数 z 通常以形式 z = x + yi编写,其中 xy 是实数, i 是具有属性 i2 = -1 的虚构单位。 复数的实际部分由 x 表示,复数的虚部由 y 表示。

Complex 类型在实例化和操作复数时使用笛卡尔坐标系(真实、虚构)。 复数可以表示为二维坐标系中的点,称为复杂平面。 复数的实际部分位于 x 轴(水平轴)上,虚部位于 y 轴(垂直轴) 上。

使用极坐标系统还可以根据复杂平面中的任何点的绝对值来表示。 在极坐标中,一个点的特点是两个数字:

  • 其数量级,它是与原点(即 0,0,或 x 轴和 y 轴相交的点)的距离。
  • 其阶段,它是真实轴与从原点到点绘制的线条之间的角度。

实例化复数

可以通过以下方法之一将值分配给复数:

  • 将两个 Double 值传递给其构造函数。 第一个值表示复数的实际部分,第二个值表示其虚部。 这些值表示二维笛卡尔坐标系中复数的位置。

  • 通过调用静态(Shared 在 Visual Basic 中) Complex.FromPolarCoordinates 方法,从其极坐标创建复数。

  • 通过将 、、、、UInt32Int16UInt64UInt16Int32Int64、 或SingleDouble值分配给对象Complex来分配Byte值。 SByte 该值将成为复数的实际部分,其虚部等于 0。

  • 通过将(在 C# 中)或转换(在 Visual Basic 中)转换为 Decimal 对象或 BigIntegerComplex 。 该值将成为复数的实际部分,其虚部等于 0。

  • 通过将方法或运算符 Complex 返回的复数分配给对象。 例如,是一个静态方法, Complex.Add 它返回一个复数,该复数是两个复数的总和,运算符 Complex.Addition 添加两个复数并返回结果。

以下示例演示了将值分配给复数的五种方法中的每一种。

using System;
using System.Numerics;

public class CreateEx
{
    public static void Main()
    {
        // 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 Main()
      ' 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 运算符使你能够使用复数执行加法、减法、乘法、除法和一元求反。
  • 对复数执行其他数值运算的方法。 除了四个基本算术运算外,还可以将复数提升为指定幂,查找复数的平方根,并获取复数的绝对值。
  • 对复数执行三角运算的方法。 例如,可以计算由复数表示的角度的正切值。

请注意,由于属性Imaginary是只读的Real,因此不能修改现有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("{0} \n{1} \nEqual: {2}", value, value2,
                                            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.PositiveInfinityDouble.NegativeInfinityDouble.NaNDouble.PositiveInfinityDouble.NegativeInfinityDouble.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 Main()
    {
        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 Main()
        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.PositiveInfinityDouble.NegativeInfinityDouble.NaN以下条件:

请注意,这适用于方法执行的任何中间计算。 例如,使用公式 (ac - bd) + (ad + bc)i 的 new Complex(9e308, 9e308) and new Complex(2.5, 3.5) 乘法。 乘法结果的实际组件计算表达式 9e308 2.5 - 9e308 3.5。 此表达式中的每个中间乘法返回Double.PositiveInfinity,并尝试从Double.PositiveInfinity返回Double.NaN中减去Double.PositiveInfinity

设置复数的格式

默认情况下,复数的字符串表示形式采用实际,)构形式(,其中数和虚数是构成复数实数和虚数分量的值的字符串表示形式。Double 此方法的某些 ToString 重载允许自定义这些 Double 值的字符串表示形式,以反映特定区域性的格式约定,或以标准或自定义数字格式字符串定义的特定格式显示。 (有关详细信息,请参阅 标准数值格式字符串自定义数字格式字符串。)

表示复数的字符串表示形式之一是 +bi,其中一种是复数的实际分量,b 是复数的虚构分量。 在电气工程中,复数通常表示为 + bj。 可以在这两种形式之一中返回复数的字符串表示形式。 为此,请通过实现 ICustomFormatterIFormatProvider 接口来定义自定义格式提供程序,然后调用 String.Format(IFormatProvider, String, Object[]) 该方法。

以下示例定义一个 ComplexFormatter 类,该类以 + bi 或 + 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)
        {
            Complex c1 = (Complex)arg;
            // Check if the format string has a precision specifier.
            int precision;
            string fmtString = String.Empty;
            if (format.Length > 1)
            {
                try
                {
                    precision = Int32.Parse(format.Substring(1));
                }
                catch (FormatException)
                {
                    precision = 0;
                }
                fmtString = "N" + precision.ToString();
            }
            if (format.Substring(0, 1).Equals("I", StringComparison.OrdinalIgnoreCase))
                return c1.Real.ToString(fmtString) + " + " + c1.Imaginary.ToString(fmtString) + "i";
            else if (format.Substring(0, 1).Equals("J", StringComparison.OrdinalIgnoreCase))
                return c1.Real.ToString(fmtString) + " + " + c1.Imaginary.ToString(fmtString) + "j";
            else
                return c1.ToString(format, provider);
        }
        else
        {
            if (arg is IFormattable)
                return ((IFormattable)arg).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 = Int32.Parse(fmt.Substring(1))
                Catch e As FormatException
                    precision = 0
                End Try
                fmtString = "N" + precision.ToString()
            End If
            If fmt.Substring(0, 1).Equals("I", StringComparison.OrdinalIgnoreCase) Then
                Return c1.Real.ToString(fmtString) + " + " + c1.Imaginary.ToString(fmtString) + "i"
            ElseIf fmt.Substring(0, 1).Equals("J", StringComparison.OrdinalIgnoreCase) Then
                Return c1.Real.ToString(fmtString) + " + " + 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 Main()
    {
        Complex c1 = new Complex(12.1, 15.4);
        Console.WriteLine("Formatting with ToString():       " +
                          c1.ToString());
        Console.WriteLine("Formatting with ToString(format): " +
                          c1.ToString("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));
    }
}
// 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 Main()
        Dim c1 As Complex = New Complex(12.1, 15.4)
        Console.WriteLine("Formatting with ToString():       " +
                          c1.ToString())
        Console.WriteLine("Formatting with ToString(format): " +
                          c1.ToString("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