To more completely illustrate complex numbers, I wrote a program with a single form that looks like this:
--------
Click Here to display the illustration
Click the Back button on your browser to return
--------
The complete code for this program is available as a download at the end of the article.
In the code, a complex number is an instance of a structure that is declared like this:
Dim myComplexNumber As ComplexNumber
myComplexNumber = New ComplexNumber(20, 30)
This gives you an instance with a Real and Imaginary property as shown below:
--------
Click Here to display the illustration
Click the Back button on your browser to return
--------
The structure that is used has this basic form:
Structure ComplexNumber
Public Real As Double
Public Imaginary As Double
Public Sub New( ...
<first New method>
End Sub
<the other New methods>
Public Overrides Function ToString() As String
...
Return <complex number string>
End Function
Public Shared Operator +(ByVal a As ComplexNumber, _
ByVal b As ComplexNumber) _
As ComplexNumber
<code to override the "+" operator>
End Operator
<code for the "-", "*", and "/" operator overrides>
End Structure
The Real and Imaginary variables become properties as shown in the earlier illustration.
The actual downloadable code has three New methods; one with two Double parameters, one with a String parameter and one with a ComplexNumber parameter. (Yes, you can use a variable declared as the structure you're defining inside the same structure. VB doesn't get confused.)
The program that can be downloaded at the end of the article includes code I added for a New method that accepts a String parameter. The problem here is that this string must be parsed to extract the 'real' and 'imaginary' parts. This, in turn, creates issues in handling positive versus negative numbers because VB includes the sign when a negative number is converted to a string but not when a positive number is. (And there is no formatting string I know of that will do the job! If anyone knows of one, send me an email!)
I used this string manipulation code to do the job:
j = InStr(sourceString, " ") - 1
Me.Real = CDbl(Left(sourceString, j))
Me.Imaginary = _
CDbl(Mid(sourceString, j + 1, _
InStr(sourceString, "i") - (j + 1)))
This might be a place where a "regular expression" would be faster. For more on this, see my article, "Regular Expressions in VB.NET".
As the code above shows, one of the problems in working with complex numbers in a program is maintaining a string representation of the number as well as an instance of the ComplexNumber structure. This program solves the problem by including an override of the ToString method. In the code that uses this structure, the overridden ToString looks like this:
Dim c As New ComplexNumber
ResultC.Text = c.ToString
Since c is an instance of ComplexNumber, the code in the structure is used instead of the Framework ToString code.
Overriding an operator has very simple syntax. Here's the complete code for overrriding the "+" operator.
Public Shared Operator +(ByVal a As ComplexNumber, _
ByVal b As ComplexNumber) _
As ComplexNumber
' -- add two complex numbers
Return New ComplexNumber(a.Real + b.Real, _
a.Imaginary + b.Imaginary)
End Operator
When the two numbers to be added are both instances of ComplexNumber, this code is called instead of the Framework code for addition. The actual procedure to add complex numbers is a math subject, not a programming subject. To understand that, you'll need a good math book.
To use this code, I simply declare the variables using the structure. Here's the code to use the overridden "+" operator.
Dim a As New ComplexNumber(FirstNumC)
Dim b As New ComplexNumber(SecondNumC)
Dim c As New ComplexNumber
c = a + b
ResultC.Text = c.ToString
One design choice I had to make was whether to maintain two copies of the complex numbers in my form code - one as an instance of ComplexNumber and the other as a String type - or convert every time I needed the number in a different format. The overridden ToString method in the structure would be used to convert. I decided to maintain two copies, so the code that is used to enter a number updates both:
FirstNumC = New ComplexNumber( _
CDbl(RealPart.Text), CDbl(ImaginaryPart.Text))
FirstNumT.Text = New ComplexNumber(FirstNumC).ToString
Because of this design choice, the New method that accepts a String that I spent so much time debugging isn't used at all! But I left it in the code in case someone else needs it someday.

