Compartilhar via


System.Numerics.Complex struct

Este artigo fornece observações complementares à documentação de referência para essa API.

Um número complexo é um número que compreende uma parte numérica real e uma parte numérica imaginária. Um número complexo z é geralmente escrito na forma z = x + yi, onde x e y são números reais, e i é a unidade imaginária que tem a propriedade i2 = -1. A parte real do número complexo é representada por x, e a parte imaginária do número complexo é representada por y.

O Complex tipo usa o sistema de coordenadas cartesianas (real, imaginário) ao instanciar e manipular números complexos. Um número complexo pode ser representado como um ponto em um sistema de coordenadas bidimensional, conhecido como plano complexo. A parte real do número complexo é posicionada no eixo x (o eixo horizontal) e a parte imaginária é posicionada no eixo y (o eixo vertical).

Qualquer ponto no plano complexo também pode ser expresso com base em seu valor absoluto, usando o sistema de coordenadas polares. Nas coordenadas polares, um ponto é caracterizado por dois números:

  • Sua magnitude, que é a distância do ponto da origem (ou seja, 0,0, ou o ponto em que o eixo x e o eixo y se cruzam).
  • Sua fase, que é o ângulo entre o eixo real e a linha traçada da origem ao ponto.

Instanciar um número complexo

Você pode atribuir um valor a um número complexo de uma das seguintes maneiras:

  • Passando dois Double valores para seu construtor. O primeiro valor representa a parte real do número complexo e o segundo valor representa sua parte imaginária. Esses valores representam a posição do número complexo no sistema de coordenadas cartesianas bidimensionais.

  • Chamando o método estático (Shared no Visual Basic) Complex.FromPolarCoordinates para criar um número complexo a partir de suas coordenadas polares.

  • Atribuindo um Bytevalor , SByte, , Int16Int32UInt16, UInt32, , Int64, , UInt64, Singleou Double a um Complex objeto. O valor se torna a parte real do número complexo e sua parte imaginária é igual a 0.

  • Convertendo (em C#) ou convertendo (no Visual Basic) um Decimal valor or BigInteger em um Complex objeto. O valor se torna a parte real do número complexo e sua parte imaginária é igual a 0.

  • Atribuindo o número complexo que é retornado por um método ou operador a um Complex objeto. Por exemplo, Complex.Add é um método estático que retorna um número complexo que é a soma de dois números complexos, e o Complex.Addition operador adiciona dois números complexos e retorna o resultado.

O exemplo a seguir demonstra cada uma dessas cinco maneiras de atribuir um valor a um número complexo.

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)

Operações com números complexos

A Complex estrutura no .NET inclui membros que fornecem a seguinte funcionalidade:

  • Métodos para comparar dois números complexos para determinar se eles são iguais.
  • Operadores para realizar operações aritméticas em números complexos. Complex permitem que você execute adição, subtração, multiplicação, divisão e negação unária com números complexos.
  • Métodos para realizar outras operações numéricas em números complexos. Além das quatro operações aritméticas básicas, você pode elevar um número complexo a uma potência especificada, encontrar a raiz quadrada de um número complexo e obter o valor absoluto de um número complexo.
  • Métodos para realizar operações trigonométricas em números complexos. Por exemplo, você pode calcular a tangente de um ângulo representado por um número complexo.

Observe que, como as Real propriedades e Imaginary são somente leitura, você não pode modificar o valor de um objeto existente Complex . Todos os métodos que executam uma operação em um Complex número, se seu valor retornado for do tipo Complex, retornam um novo Complex número.

Precisão e números complexos

As partes reais e imaginárias de um número complexo são representadas por dois valores de ponto flutuante de precisão dupla. Isso significa que Complex valores, como valores de ponto flutuante de precisão dupla, podem perder precisão como resultado de operações numéricas. Isso significa que comparações estritas para igualdade de dois Complex valores podem falhar, mesmo que a diferença entre os dois valores seja devido a uma perda de precisão. Para obter mais informações, consulte Double.

Por exemplo, realizar a exponenciação no logaritmo de um número deve retornar o número original. No entanto, em alguns casos, a perda de precisão dos valores de ponto flutuante pode causar pequenas diferenças entre os dois valores, como ilustra o exemplo a seguir.

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

Da mesma forma, o exemplo a seguir, que calcula a raiz quadrada de um Complex número, produz resultados ligeiramente diferentes nas versões de 32 bits e IA64 do .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

As partes reais e imaginárias de um número complexo são representadas por Double valores. Além de variar de Double.MinValue a Double.MaxValue, a parte real ou imaginária de um número complexo pode ter um valor de Double.PositiveInfinity, Double.NegativeInfinity, ou Double.NaN. Double.PositiveInfinity, Double.NegativeInfinity, e Double.NaN todos se propagam em qualquer operação aritmética ou trigonométrica.

No exemplo a seguir, a divisão por Zero produz um número complexo cujas partes reais e imaginárias são ambas Double.NaN. Como resultado, realizar a multiplicação com esse valor também produz um número complexo cujas partes reais e imaginárias são Double.NaN. Da mesma forma, realizar uma multiplicação que ultrapassa o intervalo do Double tipo produz um número complexo cuja parte real é Double.NaN e cuja parte imaginária é Double.PositiveInfinity. Posteriormente, realizar a divisão com este número complexo retorna um número complexo cuja parte real é Double.NaN e cuja parte imaginária é 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)

Operações matemáticas com números complexos que são inválidos ou que excedem o Double intervalo do tipo de dados não geram uma exceção. Em vez disso, eles retornam um Double.PositiveInfinity, Double.NegativeInfinity, ou Double.NaN nas seguintes condições:

Observe que isso se aplica a quaisquer cálculos intermediários realizados por um método. Por exemplo, a multiplicação de new Complex(9e308, 9e308) and new Complex(2.5, 3.5) usa a fórmula (ac - bd) + (ad + bc)i. O cálculo do componente real que resulta da multiplicação avalia a expressão 9e308 2,5 - 9e308 3,5. Cada multiplicação intermediária nesta expressão retorna Double.PositiveInfinity, e a tentativa de subtrair Double.PositiveInfinity de Double.PositiveInfinity retorna Double.NaN.

Formatar um número complexo

Por padrão, a representação de string de um número complexo assume a forma (real, imaginária), onde real e imaginário são as representações de string dos Double valores que formam os componentes reais e imaginários do número complexo. Algumas sobrecargas do ToString método permitem a personalização das representações de cadeia de caracteres desses Double valores para refletir as convenções de formatação de uma cultura específica ou para aparecer em um formato específico definido por uma cadeia de caracteres de formato numérico padrão ou personalizado. (Para obter mais informações, consulte Cadeias de caracteres de formato numérico padrão e cadeias de caracteres de formato numérico personalizado.)

Uma das formas mais comuns de expressar a representação da cadeia de caracteres de um número complexo assume a forma a + bi, onde a é o componente real do número complexo e b é o componente imaginário do número complexo. Em engenharia elétrica, um número complexo é mais comumente expresso como um + bj. Você pode retornar a representação de cadeia de caracteres de um número complexo em qualquer uma dessas duas formas. Para fazer isso, defina um provedor de formato personalizado implementando as ICustomFormatter interfaces and IFormatProvider e, em seguida, chame o String.Format(IFormatProvider, String, Object[]) método.

O exemplo a seguir define uma ComplexFormatter classe que representa um número complexo como uma cadeia de caracteres na forma de um + bi ou um + 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

O exemplo a seguir usa esse formatador personalizado para exibir a representação de cadeia de caracteres de um número complexo.

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