2016-11-11 13 views
6

は、次のコードを考えてみましょう:gcc -std=gnu99 -lmしてコンパイルC異なるOS上の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; 
} 

を、私は出力が

INF + 0であることを期待して* I

0 + 0 * I

これはLinuxで有効です(Scienti fic Linux 6.8(gcc 4.4.7)、Fedora 23(gcc 5.3.1)、およびUbuntu 14.04.5(gcc 4.8.4)です。

しかし、OS X上の(と10.11.5打ち鳴らす-602.0.53)の代わりに私が手

INF + 0 * I

ナン+ナン* I

それをclangがC99標準に準拠していないことは明らかです(N1256、第G.5.1項、厳密に言えば、標準ではなく推奨された方法です)。 実際、clangにはマクロがありません。__STDC_IEC_559_COMPLEX__が定義されています。 G.1。 clangは意図的にこの動作をしますか? UPDATE:いくつかのチェックの後、テストしたいくつかの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 は、正または符号なしの無限大を表すfloat型の定数式に展開されます。if利用可能;それ以外の場合は、変換時にオーバーフローする浮動小数点型の正の定数になります。*したがって、プラットフォーム間で動作が異なる可能性があります。 –

+0

@EugeneSh。 1.この場合、INFINITYは出力の1行目またはデバッガで確認できるように正の無限大に展開されます。 2.ここでは、単にMWEを提供するために 'INFINITY'を書いています。結論を変えずに 'complex double aaa = 1.0/0.0;'のようなあふれたものを書くことができました。私は、 'double 'の代われが' double'を 'double 'に置き換え、' creal'と 'cimag'を取り除いたことをテストしたので、実際にはうまくいきません。 、など)。 –

+0

@LeoFangそれは数学的にどのように扱われ、どのように 'printf()'がそれを表しているかは全く同じではないかもしれません。問題が本当に 'clang'かアーキテクチャかどうかを判断する最良の方法は' gcc'を使ってOSX上でコンパイルすることです。 – Havenard

答えて

1

ダブル引数に%lfの代わりに%fを使用しています。それは予測できない行動につながる、と私は思う。