Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C - unexpected behavior in complex.h on different OS

Tags:

c

clang

c99

Consider the following code:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <complex.h>
int main()
{
   complex double aaa = INFINITY + 0*I;
   printf("%.f + %.f*I\n", creal(aaa), cimag(aaa));
   complex double bbb = 1.0/aaa;
   printf("%.f + %.f*I\n", creal(bbb), cimag(bbb));
   return EXIT_SUCCESS;
}

Compiling with gcc -std=gnu99 -lm, I expect that the output is

inf + 0*I

0 + 0*I

which is true on Linux (tested on Scientific Linux 6.8 with gcc 4.4.7, Fedora 23 with gcc 5.3.1, and Ubuntu 14.04.5 with gcc 4.8.4).

However, on OS X (10.11.5 with clang-602.0.53) instead I get

inf + 0*I

nan + nan*I

It is obvious that clang does not conform the C99 standard (see N1256, Sec. G.5.1; strictly speaking, it's merely a recommended practice, not a standard). In fact, clang does not have the macro __STDC_IEC_559_COMPLEX__ defined, which is introduced in Sec. G.1. Does clang purposely make this behavior? UPDATE: after some checks I find several Linux environments that I tested do not have this macro defined either, but the code still works correctly there.

Currently, my workaround for cross-platform support is to check the macro

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <complex.h>
int main()
{
   complex double aaa = INFINITY + 0*I;
   printf("%.f + %.f*I\n", creal(aaa), cimag(aaa));
   complex double bbb = 1.0/aaa;
   #ifndef __STDC_IEC_559_COMPLEX__
   if(isnan(bbb)) 
   { 
      bbb = 0; //or do some trick that has to do with the problem context
   }
   #endif
   printf("%.f + %.f*I\n", creal(bbb), cimag(bbb));

   return EXIT_SUCCESS;
}   

But I'm not sure if it is robust...Any suggestion?

like image 857
Leo Fang Avatar asked Nov 11 '16 17:11

Leo Fang


Video Answer


1 Answers

You are using %f instead of %lf for double arguments. It leads to unpredictable behavior, I think.

like image 118
mickvav Avatar answered Sep 16 '22 17:09

mickvav