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

use CMPLX[FL]? macros instead of I #585

Merged
merged 1 commit into from
Dec 7, 2018
Merged

use CMPLX[FL]? macros instead of I #585

merged 1 commit into from
Dec 7, 2018

Conversation

fdopen
Copy link
Contributor

@fdopen fdopen commented Dec 6, 2018

The usage of I provided by "complex.h" is error-prone, e.g double complex z = Double_val(x) + I*(Double_val(y)) might give NaN as creal(z) for x = 0.0 and y = infinity.

The macros were introduced by C11, therefore I didn't make any assumptions, if they are available or not.

The usage of `I` provided by "complex.h" is error-prone, e.g `double
complex z = Double_val(x) + I*(Double_val(y))` might give `NaN` as
`creal(z)` for `x = 0.0` and `y = infinity`.
@yallop
Copy link
Owner

yallop commented Dec 7, 2018

Let me check that I understand the issue here. C11 (or, at least this draft) says:

NOTE
These macros act as if the implementation supported imaginary types and the definitions were:

#define CMPLX(x, y) ((double complex)((double)(x) + \
_Imaginary_I * (double)(y)))

and also

The macro I expands to either _Imaginary_I or _Complex_I. If _Imaginary_I is not defined, I shall expand to _Complex_I.

So the CMPLX macros are preferable to using I because they are guaranteed to use imaginary arithmetic, whereas I may use complex arithmetic on some implementations, which can result in more NaN propagation.

@fdopen
Copy link
Contributor Author

fdopen commented Dec 7, 2018

Yes, and glibc and many other stdlibs define I as _Complex_I. Therefore the surprising result is currently easy to demonstrate on the toplevel:

ComplexL.of_complex Complex.({re = 3.; im = nan});;
- : ComplexL.t = <complexld nan + nani>
ComplexL.of_complex Complex.({re = 7.; im = infinity});;
- : ComplexL.t = <complexld nan + infi>
ComplexL.of_complex Complex.({re = infinity; im = infinity});;
- : ComplexL.t = <complexld nan + infi>

_Imaginary_I is already mentioned in C99, but it is an optional feature. CMPLX was introduced by C11, but already seems to be available on more platforms.

@yallop yallop merged commit 612b533 into yallop:master Dec 7, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants