Creating Complex Math in .NET

Hello again, Math nerds, and welcome to my article. Today, I would like to show you how you can do Complex Math and work with Complex Numbers in VB.NET and in C# with the use of Operator overriding and built-in Numerics namespaces.

Complex Numbers

Complex Numbers are numbers that can be expressed in the following form:

a + bi

In this equation, a and b are real numbers, whereas i is a solution of the equation x2 = −1. This is called an imaginary number because there is no real number that satisfies the given equation. Imaginary numbers are regarded as just as real as the real numbers in mathematical science. Complex numbers give rise to the fundamental theorem of algebra, meaning: Every non-constant polynomial equation with complex coefficients has a complex solution.

Complex numbers can be applied in a variety of scientific and related areas, such as:

  • Control theory
  • Improper integrals
  • Fluid dynamics
  • Dynamic equations
  • Electromagnetism and electrical engineering
  • Signal analysis
  • Relativity
  • Geometry
  • Fractals
  • Triangles
  • Algebraic number theory
  • Analytic number theory

Our Project

Create a new Console Application in either VB.NET or C#. Once the project has loaded, add a class named clsComplexMath. Edit its constructor to look like the following code segment.

C#

      float ftReal;
      float ftImaginary;
      public clsComplex(float fReal, float fImaginary)
      {
         ftReal = fReal;
         ftImaginary = fImaginary;
      }

VB.NET

   Private ftReal As Single
   Private ftImaginary As Single
   Public Sub New(ByVal fReal As Single, ByVal fImaginary _
         As Single)
      ftReal = fReal
      ftImaginary = fImaginary
   End Sub

ftReal and ftImaginary are fields in this class that represent the Real and Imaginary numbers output through the following Properties. Add the Properties now.

C#

      public float Real
      {
         get
         {
            return (ftReal);
         }
         set
         {
            ftReal = value;
         }
      }
      public float Imaginary
      {
         get
         {
            return (ftImaginary);
         }
         set
         {
            ftImaginary = value;
         }
      }

VB.NET

   Public Property Real As Single
      Get
         Return (ftReal)
      End Get
      Set(ByVal value As Single)
         ftReal = value
      End Set
   End Property
   Public Property Imaginary As Single
      Get
         Return (ftImaginary)
      End Get
      Set(ByVal value As Single)
         ftImaginary = value
      End Set
   End Property

Now, we need to override basic operators to compensate for Complex numbers.

C#

      public static clsComplex operator +(clsComplex cOp1,
         clsComplex cOp2)
      {
         return (new clsComplex(cOp1.ftReal + cOp2.ftReal,
            cOp1.ftImaginary + cOp2.ftImaginary));
      }
      public static clsComplex operator -(clsComplex cOp1,
         clsComplex cOp2)
      {
         return (new clsComplex(cOp1.ftReal - cOp2.ftReal,
            cOp1.ftImaginary - cOp2.ftImaginary));
      }
      public static clsComplex operator *(clsComplex cOp1,
         clsComplex cOp2)
      {
         return (new clsComplex(cOp1.ftReal * cOp2.ftReal -
            cOp1.ftImaginary * cOp2.ftImaginary, cOp1.ftReal *
            cOp2.ftImaginary + cOp2.ftReal * cOp1.ftImaginary));
      }

      public static clsComplex operator /(clsComplex cOp1,
         clsComplex cOp2)
      {
         if ((cOp2.ftReal == 0.0f) && (cOp2.ftImaginary == 0.0f))
            throw new DivideByZeroException("Divide By Zero");
            float fReal = (cOp1.ftReal * cOp2.ftReal +
               cOp1.ftImaginary * cOp2.ftImaginary) / (cOp2.ftReal
               * cOp2.ftReal + cOp2.ftImaginary *
               cOp2.ftImaginary);
            float fImaginary = (cOp2.ftReal * cOp1.ftImaginary -
               cOp1.ftReal * cOp2.ftImaginary) / (cOp2.ftReal *
               cOp2.ftReal + cOp2.ftImaginary * cOp2.ftImaginary);
            return (new clsComplex(fReal, fImaginary));
      }
      public static bool operator ==(clsComplex cOp1,
         clsComplex cOp2)
      {
         if ((cOp1.ftReal == cOp2.ftReal) && (cOp1.ftImaginary
               == cOp2.ftImaginary))
            return (true);
         else
            return (false);
      }
      public static bool operator !=(clsComplex cOp1,
         clsComplex cOp2)
      {
         return (!(cOp1 == cOp2));
      }

VB.NET

   Public Shared Operator +(cOp1 As clsComplex, cOp2 _
         As clsComplex) As clsComplex
      Return (New clsComplex(cOp1.ftReal + cOp2.ftReal, _
         cOp1.ftImaginary + cOp2.ftImaginary))
   End Operator
   Public Shared Operator -(cOp1 As clsComplex, cOp2 _
         As clsComplex) As clsComplex
      Return (New clsComplex(cOp1.ftReal - cOp2.ftReal, _
         cOp1.ftImaginary - cOp2.ftImaginary))
   End Operator
   Public Shared Operator *(cOp1 As clsComplex, cOp2 As _
         clsComplex) As clsComplex
      Return (New clsComplex(cOp1.ftReal * cOp2.ftReal - _
         cOp1.ftImaginary * cOp2.ftImaginary, cOp1.ftReal * _
         cOp2.ftImaginary + cOp2.ftReal * cOp1.ftImaginary))
   End Operator
   Public Shared Operator /(cOp1 As clsComplex, cOp2 As _
         clsComplex) As clsComplex
      If ((cOp2.ftReal = 0.0F) And (cOp2.ftImaginary = 0.0F)) Then
         Throw New DivideByZeroException("Divide By Zero")
      End If
      Dim fReal As Single = (cOp1.ftReal * cOp2.ftReal + _
         cOp1.ftImaginary * cOp2.ftImaginary) / (cOp2.ftReal * _
         cOp2.ftReal + cOp2.ftImaginary * cOp2.ftImaginary)
      Dim fImaginary As Single = (cOp2.ftReal * _
         cOp1.ftImaginary - cOp1.ftReal * cOp2.ftImaginary) / _
         (cOp2.ftReal * cOp2.ftReal + cOp2.ftImaginary * _
         cOp2.ftImaginary)
      Return (New clsComplex(fReal, fImaginary))
   End Operator
   Public Shared Operator =(cOp1 As clsComplex, cOp2 As _
         clsComplex) As Boolean
      If ((cOp1.ftReal = cOp2.ftReal) And (cOp1.ftImaginary = _
            cOp2.ftImaginary)) Then
         Return (True)
      Else
         Return (False)
      End If
   End Operator
   Public Shared Operator <>(cOp1 As clsComplex, cOp2 As _
         clsComplex) As Boolean
      Return (Not (cOp1 = cOp2))
   End Operator

The operators have English counterparts, so that you can use the operators easier in your apps.

C#

      public static clsComplex Add(clsComplex cOp1,
         clsComplex cOp2)
      {
         return (cOp1 + cOp2);
      }
      public static clsComplex Subtract(clsComplex cOp1,
         clsComplex cOp2)
      {
         return (cOp1 - cOp2);
      }
      public static clsComplex Multiply(clsComplex cOp1,
         clsComplex cOp2)
      {
         return (cOp1 * cOp2);
      }
      public static clsComplex Divide(clsComplex cOp1,
         clsComplex cOp2)
      {
         return (cOp1 / cOp2);
      }
      public override bool Equals(object objEq)
      {
         clsComplex cOp2 = (clsComplex)objEq;
         return (this == cOp2);
      }

VB.NET

   Public Shared Function Add(cOp1 As clsComplex, cOp2 As _
         clsComplex) As clsComplex
      Return (cOp1 + cOp2)
   End Function
   Public Shared Function Subtract(cOp1 As clsComplex, cOp2 As _
         clsComplex) As clsComplex
      Return (cOp1 - cOp2)
   End Function
   Public Shared Function Multiply(cOp1 As clsComplex, cOp2 As _
         clsComplex) As clsComplex
      Return (cOp1 * cOp2)
   End Function
   Public Shared Function Divide(cOp1 As clsComplex, cOp2 As _
         clsComplex) As clsComplex
      Return (cOp1 / cOp2)
   End Function
   Public Overrides Function Equals(objEq As Object) As Boolean
      Dim cOp2 As clsComplex = DirectCast(objEq, clsComplex)
      Return (Me = cOp2)
   End Function

Override the ToString method.

C#

      public override int GetHashCode()
      {
         return (ftReal.GetHashCode() ^ ftImaginary.GetHashCode());
      }
      public override string ToString()
      {
         return (String.Format("({0}, {1}i)", ftReal,
            ftImaginary));
      }

VB.NET

   Public Overrides Function GetHashCode() As Integer
      Return (ftReal.GetHashCode() ^ ftImaginary.GetHashCode())
   End Function
   Public Overrides Function ToString() As String
      Return (String.Format("({0}, {1}i)", ftReal, ftImaginary))
   End Function

Apply this in your application.

C#

      public static void Main()
      {
         clsComplex cOperand1 = new clsComplex(5, 9);
         clsComplex cOperand2 = new clsComplex(3, 4);
         Console.WriteLine("Op1 + Op2 = {0}", cOperand1 +
            cOperand2);
         Console.WriteLine("Op1 - Op2 = {0}", cOperand1 -
            cOperand2);
         Console.WriteLine("Op1 * Op2 = {0}", cOperand1 *
            cOperand2);
         Console.WriteLine("Op1 / Op2 = {0}", cOperand1 /
            cOperand2);
         Console.WriteLine("Op1 == Op2: {0}", cOperand1 ==
            cOperand2);
         Console.WriteLine("Op1 != Op2: {0}", cOperand1 !=
            cOperand2);
         Console.ReadLine();
      }

VB.NET

   Sub Main()
      Dim cOperand1 As clsComplex = New clsComplex(5, 9)
      Dim cOperand2 As clsComplex = New clsComplex(3, 4)
      Console.WriteLine("Op1 + Op2 = {0}", cOperand1 + cOperand2)
      Console.WriteLine("Op1 - Op2 = {0}", cOperand1 - cOperand2)
      Console.WriteLine("Op1 * Op2 = {0}", cOperand1 * cOperand2)
      Console.WriteLine("Op1 / Op2 = {0}", cOperand1 / cOperand2)

      Console.WriteLine("Op1 == Op2: {0}", cOperand1 = cOperand2)
      Console.WriteLine("Op1 != Op2: {0}", cOperand1 <> cOperand2)
      Console.ReadLine()
   End Sub

Once run, your resulting screen will look like Figure 1.

Running
Figure 1: Running

Conclusion

It is a lot of work getting complex things done, as you can see. Stick around for more Math-based articles! Until then, happy coding.

Hannes DuPreez
Hannes DuPreez
Ockert J. du Preez is a passionate coder and always willing to learn. He has written hundreds of developer articles over the years detailing his programming quests and adventures. He has written the following books: Visual Studio 2019 In-Depth (BpB Publications) JavaScript for Gurus (BpB Publications) He was the Technical Editor for Professional C++, 5th Edition (Wiley) He was a Microsoft Most Valuable Professional for .NET (2008–2017).

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read