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:
- A divisão de um número positivo por zero retorna Double.PositiveInfinity.
- Qualquer operação que ultrapasse o limite superior do Double tipo de dados retorna Double.PositiveInfinity.
- A divisão de um número negativo por zero retorna Double.NegativeInfinity.
- Qualquer operação que ultrapasse o limite inferior do Double tipo de dados retorna Double.NegativeInfinity.
- A divisão de um zero por zero retorna Double.NaN.
- Qualquer operação executada em operandos cujos valores são Double.PositiveInfinity, Double.NegativeInfinity, ou Double.NaN retorna Double.PositiveInfinity, Double.NegativeInfinity, ou Double.NaN, dependendo da operação específica.
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