Condividi tramite


Struct System.Numerics.Complex

Questo articolo fornisce osservazioni supplementari alla documentazione di riferimento per questa API.

Un numero complesso è un numero che comprende una parte numerica reale e una parte numerica immaginaria. Un numero complesso z viene in genere scritto nel formato z = x + yi, dove x e y sono numeri reali, e i è l'unità immaginaria che ha la proprietà i2 = -1. La parte reale del numero complesso è rappresentata da x e la parte immaginaria del numero complesso è rappresentata da y.

Il Complex tipo usa il sistema di coordinate cartesiano (reale, immaginario) durante la creazione di istanze e la modifica di numeri complessi. Un numero complesso può essere rappresentato come punto in un sistema di coordinate bidimensionale, noto come piano complesso. La parte reale del numero complesso è posizionata sull'asse x (l'asse orizzontale) e la parte immaginaria è posizionata sull'asse y (asse verticale).

Qualsiasi punto nel piano complesso può essere espresso anche in base al valore assoluto, utilizzando il sistema di coordinate polari. Nelle coordinate polari, un punto è caratterizzato da due numeri:

  • La sua grandezza, ovvero la distanza del punto dall'origine (ovvero, 0,0 o il punto in cui si intersecano l'asse x e l'asse y).
  • La sua fase, ovvero l'angolo tra l'asse reale e la linea disegnata dall'origine al punto.

Creare un'istanza di un numero complesso

È possibile assegnare un valore a un numero complesso in uno dei modi seguenti:

  • Passando due Double valori al relativo costruttore. Il primo valore rappresenta la parte reale del numero complesso e il secondo valore rappresenta la parte immaginaria. Questi valori rappresentano la posizione del numero complesso nel sistema di coordinate cartesiano bidimensionale.

  • Chiamando il metodo statico (Shared in Visual Basic) Complex.FromPolarCoordinates per creare un numero complesso dalle coordinate polari.

  • Assegnando un Bytevalore , SByte, Int16, UInt16Int32, UInt64Int64SingleUInt32o Double a un Complex oggetto . Il valore diventa la parte reale del numero complesso e la sua parte immaginaria è uguale a 0.

  • Eseguendo il cast (in C#) o la conversione (in Visual Basic) di un Decimal valore o BigInteger in un Complex oggetto . Il valore diventa la parte reale del numero complesso e la sua parte immaginaria è uguale a 0.

  • Assegnando il numero complesso restituito da un metodo o un operatore a un Complex oggetto . Ad esempio, Complex.Add è un metodo statico che restituisce un numero complesso che corrisponde alla somma di due numeri complessi e l'operatore Complex.Addition aggiunge due numeri complessi e restituisce il risultato.

Nell'esempio seguente vengono illustrati ognuno di questi cinque modi per assegnare un valore a un numero complesso.

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)

Operazioni con numeri complessi

La Complex struttura in .NET include membri che forniscono le funzionalità seguenti:

  • Metodi per confrontare due numeri complessi per determinare se sono uguali.
  • Operatori per eseguire operazioni aritmetiche su numeri complessi. Complex gli operatori consentono di eseguire addizioni, sottrazione, moltiplicazione, divisione e negazione unaria con numeri complessi.
  • Metodi per eseguire altre operazioni numeriche su numeri complessi. Oltre alle quattro operazioni aritmetiche di base, è possibile aumentare un numero complesso a una potenza specificata, trovare la radice quadrata di un numero complesso e ottenere il valore assoluto di un numero complesso.
  • Metodi per eseguire operazioni trigonometriche su numeri complessi. Ad esempio, è possibile calcolare la tangente di un angolo rappresentato da un numero complesso.

Si noti che, poiché le Real proprietà e Imaginary sono di sola lettura, non è possibile modificare il valore di un oggetto esistente Complex . Tutti i metodi che eseguono un'operazione su un Complex numero, se il valore restituito è di tipo Complex, restituiscono un nuovo Complex numero.

Numeri di precisione e complessi

Le parti reali e immaginarie di un numero complesso sono rappresentate da due valori a virgola mobile e precisione doppia. Ciò significa che Complex i valori, come i valori a virgola mobile e precisione doppia, possono perdere precisione in seguito a operazioni numeriche. Ciò significa che i confronti rigorosi per l'uguaglianza di due Complex valori possono non riuscire, anche se la differenza tra i due valori è dovuta a una perdita di precisione. Per ulteriori informazioni, vedere Double.

Ad esempio, l'esecuzione di exponentiation sul logaritmo di un numero deve restituire il numero originale. In alcuni casi, tuttavia, la perdita di precisione dei valori a virgola mobile può causare lievi differenze tra i due valori, come illustrato nell'esempio seguente.

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

Analogamente, l'esempio seguente, che calcola la radice quadrata di un Complex numero, produce risultati leggermente diversi nelle versioni A 32 bit e IA64 di .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.

Infinito e NaN

Le parti reali e immaginarie di un numero complesso sono rappresentate da Double valori. Oltre a passare da Double.MinValue a Double.MaxValue, la parte reale o immaginaria di un numero complesso può avere un valore , Double.PositiveInfinityDouble.NegativeInfinityo Double.NaN. Double.PositiveInfinity, Double.NegativeInfinitye Double.NaN vengono propagati in qualsiasi operazione aritmetica o trigonometrica.

Nell'esempio seguente la divisione by Zero produce un numero complesso le cui parti reali e immaginarie sono entrambe Double.NaN. Di conseguenza, l'esecuzione della moltiplicazione con questo valore produce anche un numero complesso le cui parti reali e immaginarie sono Double.NaN. Analogamente, l'esecuzione di una moltiplicazione che esegue l'overflow dell'intervallo del tipo produce un numero complesso la Double cui parte reale è Double.NaN e la cui parte immaginaria è Double.PositiveInfinity. Successivamente l'esecuzione della divisione con questo numero complesso restituisce un numero complesso la cui parte reale è Double.NaN e la cui parte immaginaria è 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)

Le operazioni matematiche con numeri complessi non validi o che superano l'intervallo del Double tipo di dati non generano un'eccezione. Restituiscono invece un Double.PositiveInfinityoggetto , Double.NegativeInfinityo Double.NaN nelle condizioni seguenti:

Si noti che questo vale per tutti i calcoli intermedi eseguiti da un metodo. Ad esempio, la moltiplicazione di new Complex(9e308, 9e308) and new Complex(2.5, 3.5) usa la formula (ac - bd) + (ad + bc)i. Il calcolo del componente reale risultante dalla moltiplicazione valuta l'espressione 9e308 2,5 - 9e308 3,5. Ogni moltiplicazione intermedia in questa espressione restituisce Double.PositiveInfinitye il tentativo di sottrarre Double.PositiveInfinity da Double.PositiveInfinity restituisce Double.NaN.

Formattare un numero complesso

Per impostazione predefinita, la rappresentazione di stringa di un numero complesso assume la forma (reale, immaginaria), dove reale e immaginaria sono le rappresentazioni di stringa dei Double valori che formano i componenti reali e immaginari del numero complesso. Alcuni overload del ToString metodo consentono la personalizzazione delle rappresentazioni di stringa di questi Double valori per riflettere le convenzioni di formattazione di una determinata cultura o per essere visualizzate in un formato specifico definito da una stringa di formato numerico standard o personalizzata. Per altre informazioni, vedere Stringhe di formato numerico standard e stringhe di formato numerico personalizzato.

Uno dei modi più comuni per esprimere la rappresentazione di stringa di un numero complesso assume la forma di + bi, dove un è il componente reale del numero complesso e b è il componente immaginario del numero complesso. Nell'ingegneria elettrica, un numero complesso è espresso più comunemente come + bj. È possibile restituire la rappresentazione di stringa di un numero complesso in una di queste due forme. A tale scopo, definire un provider di formato personalizzato implementando le ICustomFormatter interfacce e IFormatProvider e quindi chiamare il String.Format(IFormatProvider, String, Object[]) metodo .

Nell'esempio seguente viene definita una ComplexFormatter classe che rappresenta un numero complesso sotto forma di stringa sotto forma di + bi o + 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

Nell'esempio seguente viene quindi usato questo formattatore personalizzato per visualizzare la rappresentazione di stringa di un numero complesso.

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