Структуру System.Numerics.Complex

В этой статье приводятся дополнительные замечания к справочной документации по этому API.

Комплексное число — это число, которое состоит из реальной части числа и мнимой части числа. Комплексное число z обычно записывается в форме z = x + yi, где x и y являются реальными числами, и я мнимая единица, которая имеет свойство i2 = -1. Реальная часть сложного числа представлена x, и мнимая часть сложного числа представлена y.

Тип Complex использует систему координат Декартиана (реальную, мнимую) при создании экземпляров и управлении сложными числами. Комплексное число может быть представлено как точка в двухмерной системе координат, которая называется сложной плоскости. Реальная часть сложного числа расположена на оси x (горизонтальной оси), а мнимая часть расположена на оси Y (вертикальная ось).

Любая точка в сложной плоскости также может быть выражена на основе его абсолютного значения, используя полярную систему координат. В полярных координатах точка характеризуется двумя числами:

  • Его величина, которая является расстоянием точки от источника (т. е. 0,0 или точкой, в которой пересекается ось x и y).
  • Его этап, который является углом между реальной осью и линией, нарисованной от источника до точки.

Создание экземпляра сложного числа

Можно назначить значение сложному числу одним из следующих способов:

  • Передав два Double значения конструктору. Первое значение представляет реальную часть сложного числа, а второе — мнимую часть. Эти значения представляют позицию комплексного числа в двухмерной системе координат Декартиана.

  • Вызывая статический метод (Shared в Visual Basic), Complex.FromPolarCoordinates чтобы создать комплексное число из его полярных координат.

  • Назначая объекту Byte, Int16Int32UInt32UInt16SByteUInt64SingleInt64Double или значение.Complex Значение становится реальной частью сложного числа, а его мнимая часть равна 0.

  • Путем приведения (в C#) или преобразования (в Visual Basic) Decimal или BigInteger значения в Complex объект. Значение становится реальной частью сложного числа, а его мнимая часть равна 0.

  • Назначая сложное число, возвращаемое методом или оператором объекту Complex . Например, Complex.Add является статическим методом, который возвращает комплексное число, которое является суммой двух сложных чисел, и Complex.Addition оператор добавляет два сложных числа и возвращает результат.

В следующем примере демонстрируется каждый из этих пяти способов назначения значения сложному числу.

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)

Операции со сложными числами

Структура Complex в .NET включает элементы, предоставляющие следующие функции:

  • Методы сравнения двух сложных чисел, чтобы определить, равны ли они.
  • Операторы для выполнения арифметических операций со сложными числами. Complex операторы позволяют выполнять добавление, вычитание, умножение, деление и унарное отрицание со сложными числами.
  • Методы для выполнения других числовых операций с сложными числами. Помимо четырех основных арифметических операций, можно увеличить комплексное число до указанной мощности, найти квадратный корень сложного числа и получить абсолютное значение сложного числа.
  • Методы для выполнения тригонометрических операций с сложными числами. Например, можно вычислить тангенс угла, представленного сложным числом.

Обратите внимание, что, поскольку Real Imaginary свойства доступны только для чтения, нельзя изменить значение существующего Complex объекта. Все методы, выполняющие операцию с Complex числом, если их возвращаемое значение имеет тип Complex, возвращает новое Complex число.

Точность и сложные числа

Реальные и мнимые части сложного числа представлены двумя значениями с плавающей запятой двойной точности. Это означает, что Complex значения, такие как значения с плавающей запятой двойной точности, могут потерять точность в результате числовых операций. Это означает, что строгие сравнения для равенства двух Complex значений могут завершиться ошибкой, даже если разница между двумя значениями обусловлена потерей точности. Дополнительные сведения см. в разделе Double.

Например, выполнение экспонентации в логарифме числа должно возвращать исходное число. Однако в некоторых случаях потеря точности значений с плавающей запятой может привести к незначительным различиям между двумя значениями, как показано в следующем примере.

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

Аналогичным образом, следующий пример, который вычисляет квадратный корень Complex числа, создает несколько разные результаты на 32-разрядных и IA64 версиях .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.

Бесконечность и NaN

Реальные и мнимые части сложного числа представлены значениями Double . В дополнение к диапазону от Double.MinValue Double.MaxValue, реальная или мнимая часть сложного числа может иметь значение Double.PositiveInfinity, Double.NegativeInfinityили Double.NaN. Double.PositiveInfinity, Double.NegativeInfinityи Double.NaN все распространяется в любой арифметической или тригонометрической операции.

В следующем примере деление Zero производит комплексное число, реальные и мнимые части которых являются обоими Double.NaN. В результате выполнение умножения с этим значением также создает комплексное число, реальные и мнимые части которых являются Double.NaN. Аналогичным образом, выполнение умножения, которое переполнено диапазоном Double типа, создает комплексное число, реальная часть которого и Double.NaN чья мнимая часть является Double.PositiveInfinity. Впоследствии выполнение деления с этим сложным числом возвращает комплексное число, реальная часть которого и Double.NaN мнимая часть 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)

Математические операции со сложными числами, которые являются недопустимыми или которые переполнены диапазоном Double типа данных, не вызывают исключения. Вместо этого они возвращают или Double.PositiveInfinityDouble.NegativeInfinityDouble.NaN в следующих условиях:

Обратите внимание, что это относится к любым промежуточным вычислениям, выполняемым методом. Например, умножение new Complex(9e308, 9e308) and new Complex(2.5, 3.5) использует формулу (ac - bd) + (ad + bc)i. Вычисление реального компонента, результатом которого является умножение, вычисляет выражение 9e308 2.5 – 9e308 3.5. Каждое промежуточное умножение в этом выражении возвращается Double.PositiveInfinity, и попытка вычитать Double.PositiveInfinity из Double.PositiveInfinity возвращаемого значения Double.NaN.

Форматирование сложного числа

По умолчанию строковое представление сложного числа принимает форму (реального ,мнимого, где реальные и мнимые представляют собой строковые представления Double значений, которые образуют реальные и мнимые) компоненты сложного числа. Некоторые перегрузки ToString метода позволяют настраивать строковые представления этих Double значений, чтобы отразить соглашения о форматировании определенного языка и региональных параметров или отображаться в определенном формате, определенном строкой стандартного или настраиваемого числового формата. (Дополнительные сведения см. в разделе Стандартные числовые строки формата и настраиваемые строки числовых форматов.)

Один из наиболее распространенных способов выражения строкового представления сложного числа принимает форму a + bi, где является реальным компонентом комплексного числа, а b — мнимым компонентом сложного числа. В электротехнике комплексное число чаще всего выражается как +bj. Можно вернуть строковое представление сложного числа в любой из этих двух форм. Для этого определите поставщика пользовательского формата, реализуя ICustomFormatter и IFormatProvider интерфейсы, а затем вызовите String.Format(IFormatProvider, String, Object[]) метод.

В следующем примере определяется ComplexFormatter класс, представляющий сложное число в виде строки в виде типа "+ би" или "+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

В следующем примере этот настраиваемый форматировщик используется для отображения строкового представления сложного числа.

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