Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Complex arithmetic bug: creal(0+I*Inf) -> NaN #59681

Open
jwuttke opened this issue Dec 23, 2022 · 5 comments
Open

Complex arithmetic bug: creal(0+I*Inf) -> NaN #59681

jwuttke opened this issue Dec 23, 2022 · 5 comments
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" confirmed Verified by a second party miscompilation

Comments

@jwuttke
Copy link

jwuttke commented Dec 23, 2022

In C99, there is no constructor for complex numbers. We need to write z = a + I*b. When b is Inf, then z becomes NaN. In numeric code, however, it may make perfect sense to rely on Re(z) = a.

This problem is known at since 12 years [1]. Other compilers (gcc, MSVC) do it right.

[1] https://www.mail-archive.com/freebsd-toolchain@freebsd.org/msg00000.html

@RKSimon RKSimon added clang:frontend Language frontend issues, e.g. anything involving "Sema" miscompilation and removed new issue labels Jan 5, 2023
@llvmbot
Copy link
Collaborator

llvmbot commented Jan 5, 2023

@llvm/issue-subscribers-clang-frontend

@AaronBallman AaronBallman added the confirmed Verified by a second party label Jan 24, 2023
@AaronBallman
Copy link
Collaborator

From C2x Annex G.3p1: "A complex or imaginary value with at least one infinite part is regarded as an infinity (even if its other part is a quiet NaN). A complex or imaginary value is a finite number if each of its parts is a finite number (neither infinite nor NaN). A complex or imaginary value is a zero if each of its parts is a zero."

So I believe z should be inf rather than a.

@jwuttke
Copy link
Author

jwuttke commented Jan 24, 2023

You are refering to https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3054.pdf, right?

Sect G3, which you quoted in full length, says that a+I*inf is to be regarded as infinity. This is important for function like isfinite or isnan. It has no implications whatsoever for addition.

The addition operator is treated in Sect G5.2, which however only states the obvious, and does not explicitly refer to infinities.

For our purpose most helpful is Sect G6, which specifies some function values for infinite arguments. Specfically, G6.1.1 says about the complex arccos function: "cacos(x + i∞) returns π2 − i∞, for finite x." From this it is absolutely clear that complex numbers with one finite and one infinite component should be supported as such.

@AaronBallman
Copy link
Collaborator

You are refering to https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3054.pdf, right?

Correct

Sect G3, which you quoted in full length, says that a+I*inf is to be regarded as infinity. This is important for function like isfinite or isnan. It has no implications whatsoever for addition.

I may not be understanding the summary of the issue then. I was under the impression that z = a + I*b is currently resulting in z being NaN when it should be infinity when b is infinity, but that you were looking for z to be a instead of NaN or infinity.

I might be getting thrown off by having no idea what type z, a, or b are. Or the fact that my last use of complex math was decades ago...

The addition operator is treated in Sect G5.2, which however only states the obvious, and does not explicitly refer to infinities.

For our purpose most helpful is Sect G6, which specifies some function values for infinite arguments. Specfically, G6.1.1 says about the complex arccos function: "cacos(x + i∞) returns π2 − i∞, for finite x." From this it is absolutely clear that complex numbers with one finite and one infinite component should be supported as such.

I think I agree, but given my confidence level, I'm going to CC @jcranmer-intel for a second opinion that this issue should be confirmed.

@jwuttke
Copy link
Author

jwuttke commented Jan 25, 2023

I was under the impression that z = a + I*b is currently resulting in z being NaN when it should be infinity when b is infinity, but that you were looking for z to be a instead of NaN or infinity.

I might be getting thrown off by having no idea what type z, a, or b are. Or the fact that my last use of complex math was decades ago...

Say, a and b are of type double, and z is double complex. The internal representation of z is a pair of doubles. Say, z=(re_z,im_z). So, my request is that the code line z = a + I*b should result in re_z=a and im_z=b. Which can be tested by calling the function creal(z), which always should return a, but currently does not in case that b is infinite.

netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this issue Jun 5, 2024
libcerf-2.4, released 2aug23:
  - CMake: runtime destination corrected (bin, not lib)
  - CMake: removed option PORTABLE and compiler flag -march (unavailable on some architectures)

libcerf-2.3, released 10jan23:
  - Fix compiler flags; use -O3 for Release
    - Introduce CERF_COMPILE_OPTIONS to let users overwrite the hard-coded compile options
  - Under gcc, use -march=native
    - PACKAGE MAINTAINERS: use -DPORTABLE=ON to override this !!
  - Add test coverage for erfcx, dawson, im_w_of_x (against nearby complex and status quo)
  - Avoid some divisions in function voigt (suggested by Alexander Kleinsorge)
  - Accelerate lookup in erfcx, im_w_of_x (avoid long switch, contributed by Alexander Kleinsorge)
  - Work around clang bug llvm/llvm-project#59681 (0+I*Inf->NaN)

libcerf-2.2, released 7nov22:
  - No longer raise underflow error in w_of_z for large real arg (contributed by Ethan Merritt)
  - In test suite, confound zero with values close to underflow
  - Remove some invisible files that had slipped in accidentally (noticed by Christoph Junghans)
  - Windows binary now built with Visual Studio 17 2022

libcerf-2.1, released 8apr22:
  - Provide cerfConfig.cmake (contributed by Lori A. Burns and Christoph Junghans)
  - libcerf.pc: Remove hard-coded lib/
  - Version number incremented to overcome upstream problems with withdrawn release 2.0

libcerf-1.17, released 29jun21:
  - Correct pkgconfig installation directory (use GNU install dirs, install to LIBDIR/pkgconfig)

libcerf-1.16, released 23jun21:
  - voigt_hwhm: replaced Newton's method (which failed for rare parameter combinations)
      by Illinois regula falsi (contributed by Ethan A Merritt)
  - Some internal cleanup, especially of include directives

libcerf-1.15, released 10jun21:
  - Use assertion in voigt_hwhm to check for impossible situations
      (to avoid fprintf and exit, as suggested by Ethan A Merritt)
  - Added widthtest, which tests voigt_hwhm for numerous ratios gamma/sigma
  - libcerf.pc.in: correct prefix (as suggested by Alexander Grund)
  - CMake install
    - make full use of CMAKE_INSTALL_<dir> variables
    - DESTINATION now given by LIBDIR from GNUInstallDirs
  - Support CPack for all platforms

libcerf-1.14, released 19oct20:
  - Simplified test code
  - Homepage moved to https://jugit.fz-juelich.de/mlz/libcerf, 17mar19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" confirmed Verified by a second party miscompilation
Projects
None yet
Development

No branches or pull requests

4 participants