Compartir a través de


Estructura System.Numerics.Complex

En este artículo se proporcionan comentarios adicionales a la documentación de referencia de esta API.

Un número complejo es un número que consta de una parte de número real y una parte numérica imaginaria. Un número complejo z se escribe normalmente en la forma z = x + yi, donde x e y son números reales, y i es la unidad imaginaria que tiene la propiedad i2 = -1. La parte real del número complejo se representa mediante x y la parte imaginaria del número complejo se representa mediante y.

El Complex tipo usa el sistema de coordenadas cartesiano (real, imaginario) al crear instancias y manipular números complejos. Un número complejo se puede representar como un punto en un sistema de coordenadas bidimensional, que se conoce como plano complejo. La parte real del número complejo se coloca en el eje X (el eje horizontal) y la parte imaginaria se coloca en el eje Y (el eje vertical).

Cualquier punto del plano complejo también se puede expresar en función de su valor absoluto mediante el sistema de coordenadas polares. En coordenadas polares, un punto se caracteriza por dos números:

  • Su magnitud, que es la distancia del punto desde el origen (es decir, 0,0 o el punto en el que se interseca el eje X y el eje Y).
  • Su fase, que es el ángulo entre el eje real y la línea dibujada desde el origen hasta el punto.

Creación de instancias de un número complejo

Puede asignar un valor a un número complejo de una de las maneras siguientes:

  • Pasando dos Double valores a su constructor. El primer valor representa la parte real del número complejo y el segundo valor representa su parte imaginaria. Estos valores representan la posición del número complejo en el sistema de coordenadas cartesiano bidimensional.

  • Llamando al método estático (Shared en Visual Basic) Complex.FromPolarCoordinates para crear un número complejo a partir de sus coordenadas polares.

  • Asignando un Bytevalor , , Int16UInt32Int64UInt16SByteInt32, UInt64, , Single, o Double a un Complex objeto . El valor se convierte en la parte real del número complejo y su parte imaginaria es igual a 0.

  • Al convertir (en C#) o convertir (en Visual Basic) un Decimal valor o BigInteger en un Complex objeto . El valor se convierte en la parte real del número complejo y su parte imaginaria es igual a 0.

  • Asignando el número complejo devuelto por un método o operador a un Complex objeto . Por ejemplo, Complex.Add es un método estático que devuelve un número complejo que es la suma de dos números complejos y el Complex.Addition operador agrega dos números complejos y devuelve el resultado.

En el ejemplo siguiente se muestra cada una de estas cinco formas de asignar un valor a un número complejo.

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)

Operaciones con números complejos

La Complex estructura de .NET incluye miembros que proporcionan la siguiente funcionalidad:

  • Métodos para comparar dos números complejos para determinar si son iguales.
  • Operadores para realizar operaciones aritméticas en números complejos. Complex los operadores permiten realizar sumas, restas, multiplicación, división y negación unaria con números complejos.
  • Métodos para realizar otras operaciones numéricas en números complejos. Además de las cuatro operaciones aritméticas básicas, puede elevar un número complejo a una potencia especificada, buscar la raíz cuadrada de un número complejo y obtener el valor absoluto de un número complejo.
  • Métodos para realizar operaciones trigonométricas en números complejos. Por ejemplo, puede calcular la tangente de un ángulo representado por un número complejo.

Tenga en cuenta que, dado que las Real propiedades y Imaginary son de solo lectura, no se puede modificar el valor de un objeto existente Complex . Todos los métodos que realizan una operación en un Complex número, si su valor devuelto es de tipo Complex, devuelven un nuevo Complex número.

Precisión y números complejos

Las partes reales e imaginarias de un número complejo se representan mediante dos valores de punto flotante de precisión doble. Esto significa que Complex los valores, como los valores de punto flotante de precisión doble, pueden perder precisión como resultado de operaciones numéricas. Esto significa que se pueden producir errores en comparaciones estrictas para la igualdad de dos Complex valores, incluso si la diferencia entre los dos valores se debe a una pérdida de precisión. Para obtener más información, vea Double.

Por ejemplo, realizar la exponenciación en el logaritmo de un número debe devolver el número original. Sin embargo, en algunos casos, la pérdida de precisión de los valores de punto flotante puede provocar pequeñas diferencias entre los dos valores, como se muestra en el ejemplo siguiente.

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

Del mismo modo, el ejemplo siguiente, que calcula la raíz cuadrada de un Complex número, genera resultados ligeramente diferentes en las versiones de 32 bits e IA64 de .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 y NaN

Las partes reales e imaginarias de un número complejo se representan mediante Double valores. Además de ir de Double.MinValue a Double.MaxValue, la parte real o imaginaria de un número complejo puede tener un valor de Double.PositiveInfinity, Double.NegativeInfinityo Double.NaN. Double.PositiveInfinity, Double.NegativeInfinityy Double.NaN todas se propagan en cualquier operación aritmética o trigonométrica.

En el ejemplo siguiente, la división por Zero produce un número complejo cuyos elementos reales e imaginarios son ambos Double.NaN. Como resultado, la realización de la multiplicación con este valor también genera un número complejo cuyas partes reales e imaginarias son Double.NaN. Del mismo modo, la realización de una multiplicación que desborda el intervalo del Double tipo produce un número complejo cuya parte real es Double.NaN y cuya parte imaginaria es Double.PositiveInfinity. Posteriormente, la división con este número complejo devuelve un número complejo cuya parte real es Double.NaN y cuya parte imaginaria es 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)

Las operaciones matemáticas con números complejos que no son válidos o que desbordan el intervalo del tipo de Double datos no producen una excepción. En su lugar, devuelven un Double.PositiveInfinity, Double.NegativeInfinityo Double.NaN en las condiciones siguientes:

Tenga en cuenta que esto se aplica a los cálculos intermedios realizados por un método . Por ejemplo, la multiplicación de new Complex(9e308, 9e308) and new Complex(2.5, 3.5) usa la fórmula (ac - bd) + (ad + bc)i. El cálculo del componente real resultante de la multiplicación evalúa la expresión 9e308 2.5 - 9e308 3.5. Cada multiplicación intermedia de esta expresión devuelve Double.PositiveInfinityy el intento de restar Double.PositiveInfinity de Double.PositiveInfinity devuelve Double.NaN.

Dar formato a un número complejo

De forma predeterminada, la representación de cadena de un número complejo adopta la forma (real, imaginaria), donde real e imaginaria son las representaciones de cadena de los Double valores que forman los componentes reales e imaginarios del número complejo. Algunas sobrecargas del ToString método permiten personalizar las representaciones de cadena de estos Double valores para reflejar las convenciones de formato de una referencia cultural determinada o aparecer en un formato determinado definido por una cadena de formato numérico estándar o personalizado. (Para obtener más información, consulte Cadenas de formato numérico estándar y cadenas de formato numérico personalizado).

Una de las formas más comunes de expresar la representación de cadena de un número complejo tiene la forma + bi, donde es el componente real del número complejo, y b es el componente imaginario del número complejo. En ingeniería eléctrica, un número complejo se expresa normalmente como + bj. Puede devolver la representación de cadena de un número complejo en cualquiera de estas dos formas. Para ello, defina un proveedor de formato personalizado mediante la implementación de las ICustomFormatter interfaces y IFormatProvider y, a continuación, llame al String.Format(IFormatProvider, String, Object[]) método .

En el ejemplo siguiente se define una ComplexFormatter clase que representa un número complejo como una cadena en forma de + 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

A continuación, en el ejemplo siguiente se usa este formateador personalizado para mostrar la representación de cadena de un número complejo.

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