Menu

#2552 What should imag(NaN) be?

open
nobody
2025-11-14
2022-09-30
Anonymous
No

It's probably no bug, because maybe some C function does is like that.
But maybe somebody can explain why imag(NaN) == 0 instead of NaN?

So, then NaN is only a "real"-Not-a-Number but not a complex one?

PS.
I remember a similar case about sgn(NaN) == 0.

Examples:

j = {0,1}

c1 = 1   + j*2
c2 = NaN + j*2
c3 = 1   + j*NaN
c4 = NaN + j*NaN

print c1
print c2
print c3
print c4
print ""
print real(c1), imag(c1)
print real(c2), imag(c2)
print real(c3), imag(c3)
print real(c4), imag(c4)
print ""
print real(NaN)
print imag(NaN)

Result:

{1.0, 2.0}
NaN
NaN
NaN

1.0 2.0
NaN 2.0
NaN NaN
NaN NaN

NaN
0.0

Discussion

  • Ethan Merritt

    Ethan Merritt - 2022-09-30

    Good question.
    That is one of a longer list of similar questions I have filed under "decisions to be made before the development version becomes a release candidate"

    • should sgn(NaN) return 0 or NaN?
    • should imag(NaN) return 0 or NaN?
    • should sgn(foo) return an int if foo is an int, cmplx otherwise?
    • should any of the built-in math functions return +Inf or -Inf as opposed to NaN or VERYLARGE? For example, what should gamma(-1) return?

    I had figured to eventually post the list to gnuplot-beta for discussion, but any thoughts you have now are welcome.

    I tried to see what C, Fortran, or other languages do with regard to sgn(foo) but did not find any useful guidance. Maybe it's covered in some IEEE standard?

     
  • Ethan Merritt

    Ethan Merritt - 2025-11-14

    draft c23 standard:
    ISO/IEC 9899:2024 (en) — N3220 working draft
    https://en.wikipedia.org/wiki/C23_(C_standard_revision)
    https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3220.pdf

    Annex F and Annex G describe floating point behavior involving NaN, Inf, and complex numbers. However my trials with existing C compilers indicate that many bullet points in these sections are not followed in practice. For that matter it appears to me that some of the items are ambiguous when taken in combination.

    For example and specifically relevant to this question:

    Annex F (normative)
    F.10 - "Functions with a NaN argument return a NaN result and raise no floating-point exception, except where explicitly stated otherwise."

    Annex G (normative)
    G.3 A complex value containing inf is considered inf even if the other part is NaN
    G4.3 When a value of complex type is converted to an imaginary type, the real part of the complex value is discarded and the value of the imaginary part is converted according to the conversion rules for the corresponding real types.

    So what does that guidance mean for the value of imag({NaN, Inf}) or imag({Inf, NaN})? NaN? Inf?

    As to what gnuplot is currently doing...

    • gnuplot does not distinguish between "real value" and "complex value that happens to have zero imaginary component". For operations with a separate internal code path for complex calculations A∘B, the complex code path is chosen based on testing for (imag(A) != 0) || (imag(B) != 0) .
    • NaN is a predefined variable set to {NaN,0.0}
    • treated as a real (not complex) value this returns NaN and because it is a real number the imaginary component is by definition zero.
    • treated as a complex number, the imaginary component has been preset to 0.0 so that is what is returned by imag(NaN).
    • Because of this, if one operand of an expression is NaN this does not by itself cause the code path for complex numbers to be used.

    It would be possible to change the internal value of the NaN variable to {NaN, NaN}, but this would cause all computations that see a NaN operand to use the complex code path rather than the real code path. I do not know exactly what the consequences of that would be.

    See also:
    https://sourceforge.net/p/gnuplot/bugs/2835/

     

Log in to post a comment.