### Popular Book Reviews

 Not so complex numbers in C#
Wednesday, 28 July 2010
Article Index
Not so complex numbers in C#
Complex functions

## Complex functions

As well as creating Complex objects using the Cartesian form you can also use the static FromPolarCoodinates method:

`z3 = Complex.FromPolarCoordinates(                             1,Math.PI/2);`

As well as complex addition you can use subtraction, multiplication, division and unary negation. The operators also work with mixed real and complex values. For example you can write:

`int t = 2;z = z*t + t;`

The inequality operator is also overloaded allowing you to compare two complex values.

Of course the greater than less than operators are not defined because the concept of greater than/less than makes no sense for complex numbers.

All of the overloaded operators are also available as static methods.

Notice that we can convert between polar and Cartesian form immediately because of the Magnitude and Phase properties. Of course these are read-only as already mentioned.

The fact that we have the usual arithmetic operations is all very well but to do anything useful with complex number we also need some higher operations and functions. In particular we need a power operator. It is one of the peculiarities of C# that it doesn't support a raise to the power operator.

Where other languages would write X^2 or X**2 C# uses Math.Pow(X,2), which to any mathematically trained person is barbaric.

There are arguments for why C# does it this way - but none justify the loss of a power operator.To make things worse the ^ operator is defined as XOR which makes it possible to translate a formula incorrectly but not realise what the problem is until much time has been wasted.

The Complex type simply adds its own version of Pow. If you write Complex.Pow(Z,X) then it will compute Z^X where X is a double. So to square Z you would write

`Complex.Pow(Z,2);`

In most cases it would be better to write Z*Z or Z*Z*Z rather than use the Pow method. As these forms are much more efficient than a general power calculation which generally involves logs and inverse logs doing things this way is no bad thing.

There is also a doubly complex Pow method Pow(Z1,Z2) where both are complex and this computes Z1Z2. Don't use it if Z2 is in fact real because it's not very fast.

Once you have got over the shock of the way that you calculate a power the rest of the Complex functions look reasonable. There is a conjugate method for example but no unary conjugate operator and a Reciprocal method that works out 1/z - hopefully faster and more accurately than doing the division. All of the complex trig and hyperbolic functions are defined. Inverse trig functions are provided but not inverse hyperbolic. Natural log, log to any base and log to base 10 are provided as is Exp. Other functions can generally be made up using these as the building blocks.

At this point what could be more appropriate than to program the most incredible formula in the mathematical world. As is well known (I hope)

`  eiPi  =-1`

Thus relating together the numbers e, i, Pi and -1.

In C# this becomes:

`Complex z = Complex.Exp(    Complex.ImaginaryOne * Math.PI);Console.WriteLine(z.ToString());`

The result printed is:

`(-1, 1.22460635382238E-16)`

which isn't quite (-1,0) and this should also give you some idea of the (in)accuracy involved in using complex Exp.

## Formatting

One last topic - formatting complex numbers. The ToString method has a number of overloaded versions that can be used to apply a custom format. As we have already seen the simple ToString() method returns a string formatted as (real,imaginary).

The ToString(string) method will apply a standard format string to the two double precision values that make up the number. You can look up "Standard Numeric Format Strings" in the documentation.  For example:

`Complex z = Complex.Exp(      Complex.ImaginaryOne * Math.PI);Console.WriteLine(z.ToString("F3"));`

outputs:

`(-1.000, 0.000)`

That is two fixed point values with 3 digits after the decimal point. You can only use format specifiers that apply to Double.

The methods ToString(IFormatProvider) and ToString(string,IFormatProvider) will format the number using the culture specified by the IFormatProvider and in the second case will also format the doubles using the format string.

For example:

`Console.WriteLine( z.ToString( new CultureInfo("es-ES")));Console.WriteLine( z.ToString("F3",new CultureInfo("es-ES")));`

displays:

`(-1, 1,22460635382238E-16)(-1,000, 0,000)`

Note: es-ES is the specifier for Spanish and Spain.

The documentation contains an example of building a custom formatter that can be used to print values in the form a+ib or a+jb. However because you can't inherit from a struct  and even adding extension methods is difficult trying to extend Complex in any reasonably object-oriented way is doomed to fail.

If you would like to see an example of Complex in use then see:

Mandelbrot Zoomer in WPF

If you would like to be informed about new articles on

Each provides a full list of what's new each week - usually five hot book reviews, five thought-provoking articles and five not to be missed news items - in a compact click-to-read form.

 Dynamic C# What exactly is C#'s dynamic type all about? Is it dynamic or is it just static typing under cover? And how does it change things like early binding, virtual and non-virtual? + Full Story Getting started with C# Metro appsHow does Metro development in C# differ from desktop development? After looking at some general differences and the overall structure of a Metro app, we move on to consider how to make use of asynchro [ ... ] + Full Story Other Articles

<ASIN:0387257683>

<ASIN:0521706858>

<ASIN:0321637135>

<ASIN:0521880688>

<ASIN:818561816X>

<ASIN:3540739157>

<ASIN:0954612078>

Last Updated ( Wednesday, 04 August 2010 )