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 方法,從其極座標建立複數。

  • ByteSByteUInt32UInt16Int32Int16Int64UInt64SingleDouble 值指派給 Complex 物件。 值會變成複數的實際部分,其虛數部分等於0。

  • 藉由將 (在 C# 中) 或轉換 (在 Visual Basic 中) DecimalBigInteger 值轉換為 Complex 物件。 值會變成複數的實際部分,其虛數部分等於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 運算子可讓您使用複數執行加法、減法、乘法、除法和一元負數。
  • 對複數執行其他數值運算的方法。 除了四個基本算術運算之外,您還可以將複數提升為指定的乘冪、尋找複數的平方根,並取得複數的絕對值。
  • 對複數執行三角運算的方法。 例如,您可以計算以複數表示的角度正切值。

請注意,由於 RealImaginary 屬性是唯讀的,所以您無法修改現有 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.

Infinity 和 NaN

複數的實數和虛數部分會以 Double 值表示。 除了從 Double.MinValueDouble.MaxValue,複數的實數或虛數部分也可以有、 Double.NegativeInfinityDouble.NaN的值Double.PositiveInfinityDouble.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.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.NaNDouble.PositiveInfinity去 。

格式化複數

根據預設,複數的字串表示會採用實際,)數的形式(,其中 realimaginary 是構成複數之實數和虛數位元件的字串表示。Double 方法的某些 ToString 多載允許自定義這些 Double 值的字串表示法,以反映特定文化特性的格式慣例,或以標準或自定義數值格式字串所定義的特定格式顯示。 (如需詳細資訊,請參閱 標準數值格式字串自訂數值格式字串。)

表達複數位符串表示法的其中一種較常見方式是 a + bi,其中 a 是複數的實際元件,而 b 是複數的虛數元件。 在電氣工程中,複數最常以 + bj 表示。 您可以使用這兩種形式之一傳回復數的字串表示。 若要這樣做,請實 ICustomFormatter 作 和 IFormatProvider 介面來定義自定義格式提供者,然後呼叫 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