3
votes

In real floating point arithmetic we have the additional symbols INF (infinity), NAN and the signed zero. For complex arithmetic this is more difficult. If one uses the "naive" rules for multiplication and division

(a + ib)(c + id) = (ac - db) + i(ac+bd)
(a + ib)/(c + id) = ( (ac + db) + i(ac-bd) ) / (c*c + d*d)

one gets wrong (*) results for almost all cases where where one variable of a,b,c,d is INF or NAN.

For example

  • (1 + i0)*(INF + i0) = INF + iNAN . As compared to real arithmetic 1*INF = INF
  • (0 + i1)* (NAN + i0) = NAN + iNAN. However one would expect i*NAN = (0+iNAN)
  • 1 / (0+0i) = NAN + iNAN. This breaks for example z = 1/(1/z), which works perfectly in real arithmetic.

This list could go on easily.

The question is, how to correctly implement the complex division and multiplication so that all cases, including when one of real or imaginary part is INF and NAN, give meaningful results? Also are there programming languages which guarantee correct behavior for complex arithmetic with INF and NAN?

EDIT: I would like to know which programming language standard (version) does require correct complex arithmetic with INF and NAN. The languages I would be most interested are the C, C++ and FORTRAN families.

(*) wrong in the sense that it is mathematically not meaningful, or is counter-intuitive in the sense of IEEE-754.

1
In what context? What language? Here is clang's C++ <complex> implementation. If you look at the operator * implementation, it demonstrates how INF/NaN are handled. What do disagree with? - Brett Hale
They seem to do it right. Thanks for the link. My question is which language guarantees it., i.e. in which language the specification mandates correct INF and NAN behavior. To my knowledge this is not the case for C++ (But I could be wrong). FORTRAN also does not seem to require it. Here I would like to have clarity. - Andreas H.
The thing is, if you want to write portable code that relies on handling INF and NAN, it is pointless if some compilers do it right and some others dont. - Andreas H.

1 Answers

3
votes

For C, please check out Annex G in C99 or C11. At least GCC follows this, I would be surprised if clang didn't.

For C++, IIRC the C++ standard has chosen to not incorporate C99/C11 Annex G, and the algorithms for complex mult/div is up to the implementation.

The Fortran standard does not specify how complex multiplication or division must be implemented. For division, GFortran uses the common Smith (1962) method, except when -ffast-math is specified, then the naive algorithm is used.

For a comparison of different algorithms for computing complex division, please see http://arxiv.org/abs/1210.4539