内C - complex.h意外的行为在不同的操作系统

问题描述:

考虑下面的代码:内C - complex.h意外的行为在不同的操作系统

#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; 
} 

gcc -std=gnu99 -lm编译,我期望输出

INF + 0 * I

0 + 0 * I

这在Linux上是正确的(在Scienti上测试过使用gcc 4.4.7的fic Linux 6.8,使用gcc 5.3.1的Fedora 23以及使用gcc 4.8.4的Ubuntu 14.04.5)。

然而,在OS X(10.11.5铿锵-602.0.53),而不是我得到

INF + 0 * I

囡楠+ * I

它很显然,叮当不符合C99标准(见N1256,G.5.1节;严格地说,这只是一个推荐的做法,而不是一个标准)。 实际上,clang没有定义的宏__STDC_IEC_559_COMPLEX__,这是在第2节中介绍的。 G.1。铿锵有意做出这种行为? 更新:经过一些检查后,我发现我测试的几个Linux环境没有定义这个宏,但代码在那里仍然正常工作。

目前,我的跨平台支持的解决方法是检查宏观

#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; 
} 

但我不知道这是否是稳健的...任何建议?

+2

[C标准](http://port70.net/~nsz/c/c11/n1570.html#7.12p4):* INFINITY 扩展为浮点类型的常量表达式,表示正或无符号无穷大,if可用的;否则就是在翻译时溢出的浮点类型的正常数。*因此,跨平台的行为可能不完全相同...... –

+0

@EugeneSh。 1.在这种情况下,INFINITY可以扩展到正无穷大,这可以通过第一行输出来检查,或者在调试器中检查;在这里我写'INFINITY'只是为了提供一个MWE。你可以写出像'complex double aaa = 1.0/0.0;'这样溢出的东西而不改变结论; 3.如果这不起作用是没有意义的,因为我已经测试过一个“double”对象(把所有'complex double'替换为'double',将函数'creal'和'cimag'去掉等)。 –

+0

@LeoFang它是如何在数学上处理的,以及'printf()'代表的可能不是完全相同的东西。也许最好的方法来确定问题是否真的是'clang'或架构是通过使用'gcc'在OSX上编译它。 – Havenard

对于双重参数,您正在使用%f而不是%lf。这导致了不可预测的行为,我想。