3
votes

I'm implementing my own programming language for fun, and have been playing around with the implementation of various floating point numeric types. I'd like to think about implementing a numeric type to represent complex numbers.

i) I've been reading around, and my understanding is that there is no equivalent of the IEEE-754 standard (which defines standard floating-point representations of real numbers) for complex numbers. Is that correct, or have I missed something?

ii) All programming languages that I'm aware of implement complex types by storing a pair of (either single- or double-precision) floating-point numbers, which represent the Cartesian form of a complex number $x + iy$. Is anyone aware of a programming language that does things differently?

I'd like to consider implementing a numeric type that represents complex numbers in polar form $re^{i\theta}$, storing $r$ as an unsigned floating-point number and $\theta$ as an unsigned fixed-point number between 0 and 1. This would be quite a non-standard thing to do (but remember I'm just doing my programming language for fun). As far as I'm aware, there are very few settings that use unsigned floating-point numbers, but it feels like this would be an appropriate use for them. I'd want $\theta$ to be stored as fixed-point in order to give an even spread around the origin.

Is anyone aware of any work that has been done on the numerical consequences of such a choice? For example: what is the relative importance, in a typical mathematical workflow, of addition vs multiplication of complex numbers (addition being easier in Cartesian form, multiplication being easier in polar form)? What would be the implications of a choice of a polar representation in terms of numerical precision and accuracy? Are there any references that anyone could point me to please?

NB - please note that I'm not interested in the existence of any hardware support for these numeric types. Since I'm doing my language for fun, I'm happy to do things in software as a learning exercise.

Finally - does anyone have any suggestions about how a complex equivalent of Inf should behave?

1
I guess your theta would essentially be an integer, giving the "compass" direction. For example, with a 4-bit integer, you would have 2**4 = 16 different directions. Of course you want something like 64 bits, and not just 4, but the principle would be the same. Your r could be an ordinary IEEE floating point where you just disregard the sign bit. For the question of arithmetic with infinity, see e.g. Riemann sphere § Arithmetic operations.Jeppe Stig Nielsen
It could be useful to have, in cartesian representation, a number like x+Iinf or Inf+Iy where x and y are finite. This would be difficult in a polar representationdmuir
@EricPostpischil my bad. I remembered doing that in boost or something library like that. In C++ it's a template so it's definitely possible to have std::complex<int>phuclv
C99 also has a dedicated imaginary type for representing numbers of the form $iy$ with no real component. But its general complex type is the usual Cartesian representation.dan04

1 Answers

2
votes

One thing to bear in mind is that although multiplication in a polar representation is somewhat, say a factor of 2, faster than multiplication in cartesians, addition in polars is a lot slower than addition in cartesians. In C, with code compiled -O3 I see addition in polars as being around 250 times slower than addition in cartesians. This is because to do the addition you have to first convert to cartesians, which is two calls to both sin() and cos(), then add and then convert back to polars, which is a call to hypot (or at least sqrt) and atan2.

As for how much the various operations are used, its hard to be definite. If you are going to do matrix and vector operations (and complex matrices are common in boith physics and electrical engineering) then I'd guess addition and multiplication enter about equally.