Submitter:Fred J. Tydeman
Submission Date:2017-02-23
Document: WG14 N2116

Problem being solved

Annex G.5.1#4 is missing some properties of complex arithmetic. Since they are not part of the standard, many implementations get them wrong. In particular, complex numbers where one part is finite and the other part is a NaN, are treated wrong.

One needs to think in both rectangular and polar terms. So, CMPLX(finite,NaN), as a vector, is at least as long as the finite part.

If a NaN part of a complex number used in a computation is replaced by any finite or infinite number and the result of the computation is the same non-NaN, then that result is the correct answer (not a NaN).

So, CMPLX(infinity,any) * CMPLX(3,NaN) is an infinity no matter what finite or infinite value is used in place of the NaN.

And, CMPLX(3,NaN) / CMPLX(0,0) is an infinity no matter what finite or infinite value is used in place of the NaN.

And, CMPLX(0,0) / CMPLX(3,NaN) is a zero no matter what finite or infinite value is used in place of the NaN.

Solution

Add the following to Annex G.3 Conventions:

A non-zero is anything other than: zero, CMPLX(0,NaN), CMPLX(NaN,0), CMPLX(NaN,NaN), e.g., one of its parts is nonzero finite or infinity and the other part is finite, infinity, or NaN.

If a NaN part of a complex number used in a computation is replaced by any finite or infinite number and the result of the computation is the same non-NaN, then that result is the correct answer (not a NaN).

Change the following in Annex G.5.1#4 Multiplicative operators

"infinity properties" to "zero and infinity properties"

Change 1st bullet from:

-- if one operand is an infinity and the other operand is a nonzero finite number, then the result of the * operator is an infinity.

to:

-- if one operand is an infinity and the other operand is a non-zero, then the result of the * operator is an infinity.

Change 4th bullet from:

-- if the first operand is a nonzero finite number or an infinity and the second operand is a zero, then the result of the / operator is an infinity

to:

-- if the first operand is a non-zero and the second operand is a zero, then the result of the / operator is an infinity.

Add the following to Annex G.5.1#4

-- if one operand is a zero and the other operand is finite, then the result of the * operator is a zero.

-- if the first operand is a zero and the second operand is a non-zero, then the result of the / operator is a zero.

There are some other properties that could be added (but they are not as important).

Other properties

w/w is CMPLX(1,0) for all finite w (except zero).

cimag(w*conj(w)) is zero for everything except CMPLX(NaN,NaN).

Existing practice

Based upon my testing, each of the above requirements has been implemented by at least one implementation, however, it is not clear if there are any implementations that do them all.