4.7 Special Values, Signed Zeroes and Branch Cuts

When evaluating a function in an argument whose real or imaginary part is a special value (that is NaN or a (signed) infinity) or a (signed) zero, our goal is to compute the same result as specified for the corresponding function in the C standard.

More precisely, we implement the following principles for real numbers (which appear to be consistent with the C standard). The value +\infty is considered as the limit of sequences of positive numbers tending to infinity, -\infty as the limit of sequences of negative numbers with absolute values tending to infinity. To handle division by infinities it is then natural to also consider signed zeroes as limits of sequences, namely +0 and -0 as the limits of sequences of positive resp. negative numbers with absolute value tending to zero, so that we obtain for the division of two real numbers that 1/+\infty=+0, 1/-\infty=-0, 1/+0=+\infty and 1/-0=-\infty. On the other hand, +0/+0=NaN and +\infty/+\infty=NaN, since any value is possible depending on how fast the dividend and divisor sequences, respectively, tend to zero or infinity. There is only one, unsigned, NaN value representing not a number; and any formula involving a NaN results in a NaN.

A peculiarity arises when adding signed zeroes; clearly, (+0)+(+0)=+0 and (-0)+(-0)=-0, but what should the result of (+0)+(-0) be? If each operand is replaced by a sequence of positive resp. negative real numbers tending to zero, then the sequence of their sums may or may not have a common sign (it could even be alternating between positive and negative). A logical result would be an unsigned zero, but this is not foreseen by the IEEE-754 standard since the binary format reserves one bit for the sign, so that every number has either a plus or a minus sign (which is ignored for NaN). So in case the sign of a resulting zero cannot be determined, the result is arbitrarily fixed to be +0. One could imagine a fourth type of zero, the exact zero; such a number is also not foreseen by the standard, so that any zero input to a function is considered signed, and as for other numbers, “inexact” output (here, an arbitrarily assigned plus sign) is considered “exact” as an input to a subsequent function call. Beware that although +0 and -0 differ in sign, they nevertheless compare as equal; so equal function inputs may lead to differing results!

Since complex numbers are given through their real and imaginary parts, there are in fact four different complex zeroes depending on the signs (all of which compare as equal).

Signs in parts of complex numbers become meaningful when branch cuts come into play. The complex logarithm, for instance, is defined up to integer multiples of 2 \pi i, since exp(2 \pi i) = 1. More precisely, when trying to define the logarithm as a continuous function, one walk on a circle around the origin leads to values that differ by 2 \pi i. So there is necessarily a discontinuity, which is placed along a branch cut. In GNU MPC, the chosen branch cuts are the same as those specified for the corresponding functions in the C standard. For instance, the complex logarithm has a branch cut along the negative real axis (which in particular leads to results coinciding with GNU MPFR on the positive real axis). Since -1+0i can be seen as above the branch cut, but -1-0i can be seen as below the branch cut, we compute the exact results log(-1+0i)=+0+\pi i and log(-1-0i)=+0-\pi i (and round to a representable dyadic number), where the imaginary parts differ by 2 \pi i and the signs of the real parts cannot be determined and are thus set to plus. (In fact extending the preceding arguments, we can also consider the exact finite value -1 as the limit of a sequence tending to -1; then the real part of the result tends to zero and is positive when -1 is approached from below on the real axis and negative when -1 is approached from above on the real axis.)

This semantics becomes fuzzy when mixed operations between complex and real numbers enter the game. Two different approaches stand out. First of all, a real value may first be promoted to a complex value, and then the previous rules apply. For instance, with this approach, (1-0i)+(+0)=(1-0i)+(+0+0i)=1+0i, where the sign of the imaginary part of the result cannot be determined and is thus set to plus. Alternatively, the zero imaginary part of the real number may be interpreted as an exact zero; then (1-0i)+(+0)=1-0i. The C standard appears to follow the second approach, which we thus also adopt in MPC.

4.8 Exceptions

This version of GNU MPC does not support exceptions (invalid, division by zero, overflow, underflow, inexact). A future version might support them, through the GNU MPFR mechanism for supporting exceptions.