System.Numerics.Complex, struktura

Ten artykuł zawiera dodatkowe uwagi dotyczące dokumentacji referencyjnej dla tego interfejsu API.

Liczba zespolona to liczba, która składa się z części liczb rzeczywistych i części wyimaginowanej liczby. Liczba ze zespolona jest zwykle zapisywana w postaci z = x + yi, gdzie x i y są liczbami rzeczywistymi, a i jest wyimaginowaną jednostką, która ma właściwość i2 = -1. Rzeczywista część liczby zespolonej jest reprezentowana przez x, a wyimaginowana część liczby zespolonej jest reprezentowana przez y.

Typ Complex używa układu współrzędnych kartezjańskich (rzeczywistych, wyimaginowanych) podczas tworzenia wystąpienia i manipulowania liczbami zespolonymi. Liczba zespolona może być reprezentowana jako punkt w dwuwymiarowym układzie współrzędnych, który jest znany jako płaszczyzna zespolona. Rzeczywista część liczby zespolonej jest umieszczona na osi x (osi poziomej), a część wyimaginowana jest umieszczona na osi y (oś pionowa).

Każdy punkt w płaszczyźnie złożonej może być również wyrażony na podstawie jego wartości bezwzględnej przy użyciu układu współrzędnych polarnych. We współrzędnych polarnych punkt charakteryzuje się dwiema liczbami:

  • Jego wielkość, która jest odległością punktu od źródła (czyli 0,0 lub punktu, w którym oś x i oś y przecinają się).
  • Jego faza, która jest kątem między osią rzeczywistą a linią pobraną z punktu początkowego do punktu.

Tworzenie wystąpienia liczby zespolonej

Wartość można przypisać do liczby zespolonej na jeden z następujących sposobów:

  • Przekazując dwie Double wartości do konstruktora. Pierwsza wartość reprezentuje rzeczywistą część liczby zespolonej, a druga wartość reprezentuje jego wyimaginowaną część. Te wartości reprezentują położenie liczby zespolonej w dwuwymiarowym układzie współrzędnych kartezjańskich.

  • Wywołując metodę static (Shared w Visual Basic), Complex.FromPolarCoordinates aby utworzyć liczbę zespolonej na podstawie współrzędnych polarnych.

  • Przypisując do obiektu wartość Byte, SByte, UInt16Int64UInt32UInt64Int32Int16, , Singlelub .DoubleComplex Wartość staje się rzeczywistą częścią liczby zespolonej, a jej wyimaginowana część równa 0.

  • Rzutując (w języku C#) lub konwertując (w Visual Basic) Decimal wartość lub BigInteger na Complex obiekt. Wartość staje się rzeczywistą częścią liczby zespolonej, a jej wyimaginowana część równa 0.

  • Przypisując liczbę zespolona zwracaną przez metodę Complex lub operator do obiektu. Na przykład Complex.Add jest to metoda statyczna zwracająca liczbę zespolona, która jest sumą dwóch liczb zespolonych, a Complex.Addition operator dodaje dwie liczby zespolone i zwraca wynik.

Poniższy przykład przedstawia każdy z tych pięciu sposobów przypisywania wartości do liczby zespolonej.

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)

Operacje z liczbami złożonymi

Struktura Complex na platformie .NET zawiera elementy członkowskie, które zapewniają następujące funkcje:

  • Metody porównywania dwóch liczb zespolonych w celu określenia, czy są równe.
  • Operatory do wykonywania operacji arytmetycznych na liczbach zespolonych. Complex operatory umożliwiają wykonywanie dodawania, odejmowania, mnożenia, dzielenia i jednoargumentowego negacji ze złożonymi liczbami.
  • Metody wykonywania innych operacji liczbowych na liczbach zespolonych. Oprócz czterech podstawowych operacji arytmetycznych można podnieść liczbę zespolona do określonej mocy, znaleźć pierwiastek kwadratowy liczby zespolonej i uzyskać wartość bezwzględną liczby zespolonej.
  • Metody wykonywania operacji trygonometrycznych na liczbach zespolonych. Na przykład można obliczyć tangens kąta reprezentowanego przez liczbę zespoloną.

Należy pamiętać, że ponieważ Real właściwości i Imaginary są tylko do odczytu, nie można zmodyfikować wartości istniejącego Complex obiektu. Wszystkie metody, które wykonują operację na Complex liczbie, jeśli ich wartość zwracana jest typu Complex, zwraca nową Complex liczbę.

Precyzja i liczby zespolone

Rzeczywiste i wyimaginowane części liczby zespolonej są reprezentowane przez dwie wartości zmiennoprzecinkowe o podwójnej precyzji. Oznacza to, że Complex wartości, takie jak wartości zmiennoprzecinkowe o podwójnej precyzji, mogą utracić precyzję w wyniku operacji liczbowych. Oznacza to, że ścisłe porównania równości dwóch Complex wartości mogą zakończyć się niepowodzeniem, nawet jeśli różnica między dwiema wartościami jest spowodowana utratą precyzji. W celu uzyskania więcej informacji, zobacz następujący temat: Double.

Na przykład wykonanie wykładnika w logarytmie liczby powinno zwrócić oryginalną liczbę. Jednak w niektórych przypadkach utrata dokładności wartości zmiennoprzecinkowych może spowodować niewielkie różnice między dwiema wartościami, jak pokazano w poniższym przykładzie.

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

Podobnie poniższy przykład, który oblicza pierwiastek Complex kwadratowy liczby, generuje nieco inne wyniki w 32-bitowych wersjach i IA64 platformy .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.

Nieskończoność i NaN

Rzeczywiste i wyimaginowane części liczby zespolonej są reprezentowane przez Double wartości. Oprócz zakresu od Double.MinValue do Double.MaxValue, rzeczywista lub wyimaginowana część liczby zespolonej może mieć wartość Double.PositiveInfinity, Double.NegativeInfinitylub Double.NaN. Double.PositiveInfinity, Double.NegativeInfinityi Double.NaN wszystkie propagują się w dowolnej operacji arytmetycznej lub trygonometrycznej.

W poniższym przykładzie dzielenie przez Zero tworzy liczbę zespoloną, której rzeczywiste i wyimaginowane części to .Double.NaN W rezultacie mnożenie z tą wartością powoduje również utworzenie liczby zespolonej, której rzeczywiste i wyimaginowane części to Double.NaN. Podobnie wykonanie mnożenia, które przepełnia zakres Double typu, powoduje utworzenie liczby zespolonej, której rzeczywista część jest Double.NaN i której wyimaginowaną częścią jest Double.PositiveInfinity. Następnie wykonanie dzielenia z tą liczbą zespoloną zwraca liczbę zespoloną, której rzeczywista część jest Double.NaN i której wyimaginowaną częścią jest 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)

Operacje matematyczne z liczbami zespolonymi, które są nieprawidłowe lub które przepełniają zakres Double typu danych, nie zgłaszają wyjątku. Zamiast tego zwracają wartość Double.PositiveInfinity, Double.NegativeInfinitylub Double.NaN w następujących warunkach:

Należy pamiętać, że dotyczy to wszelkich obliczeń pośrednich wykonywanych przez metodę. Na przykład mnożenie new Complex(9e308, 9e308) and new Complex(2.5, 3.5) formuły (ac - bd) + (ad + bc)i. Obliczenie rzeczywistego składnika, który wynika z mnożenia, oblicza wyrażenie 9e308 2.5 - 9e308 3.5. Każde mnożenie pośrednie w tym wyrażeniu zwraca wartość Double.PositiveInfinity, a próba odejmowania Double.PositiveInfinity z Double.PositiveInfinity zwraca wartości Double.NaN.

Formatowanie liczby zespolonej

Domyślnie reprezentacja ciągu liczby zespolonej przyjmuje postać (realną wyimaginowaną, gdzie rzeczywiste, i wyimaginowane) są reprezentacje ciągów Double wartości, które tworzą rzeczywiste i wyimaginowane składniki liczby zespolonej. Niektóre przeciążenia ToString metody umożliwiają dostosowanie reprezentacji ciągów tych Double wartości w celu odzwierciedlenia konwencji formatowania określonej kultury lub wyświetlania w określonym formacie zdefiniowanym przez standardowy lub niestandardowy ciąg formatu liczbowego. (Aby uzyskać więcej informacji, zobacz Standardowe ciągi formatu liczbowego i niestandardowe ciągi formatu liczbowego.

Jednym z bardziej typowych sposobów wyrażania reprezentacji ciągu liczby zespolonej jest postać + bi, gdzie element jest rzeczywistym składnikiem liczby zespolonej, a b jest składnikiem wyimaginowanym liczby zespolonej. W inżynierii elektrycznej liczba zespolona jest najczęściej wyrażana jako + bj. Możesz zwrócić reprezentację ciągu liczby zespolonej w jednej z tych dwóch formularzy. W tym celu zdefiniuj niestandardowego dostawcę formatu, implementując ICustomFormatter interfejsy i IFormatProvider , a następnie wywołaj metodę String.Format(IFormatProvider, String, Object[]) .

W poniższym przykładzie zdefiniowano klasę ComplexFormatter reprezentującą liczbę zespolone jako ciąg w postaci + bi lub + 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

W poniższym przykładzie użyto tego niestandardowego formatowania, aby wyświetlić reprezentację ciągu liczby zespolonej.

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