6
考慮下面的代碼:內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沒有定義的宏鏗鏘有意做出這種行爲? 更新:經過一些檢查後,我發現我測試的幾個Linux環境沒有定義這個宏,但代碼在那裏仍然正常工作。__STDC_IEC_559_COMPLEX__
,這是在第2節中介紹的。 G.1。
目前,我的跨平臺支持的解決方法是檢查宏觀
#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;
}
但我不知道這是否是穩健的...任何建議?
[C標準](http://port70.net/~nsz/c/c11/n1570.html#7.12p4):* INFINITY 擴展爲浮點類型的常量表達式,表示正或無符號無窮大,if可用的;否則就是在翻譯時溢出的浮點類型的正常數。*因此,跨平臺的行爲可能不完全相同...... –
@EugeneSh。 1.在這種情況下,INFINITY可以擴展到正無窮大,這可以通過第一行輸出來檢查,或者在調試器中檢查;在這裏我寫'INFINITY'只是爲了提供一個MWE。你可以寫出像'complex double aaa = 1.0/0.0;'這樣溢出的東西而不改變結論; 3.如果這不起作用是沒有意義的,因爲我已經測試過一個「double」對象(把所有'complex double'替換爲'double',將函數'creal'和'cimag'去掉等)。 –
@LeoFang它是如何在數學上處理的,以及'printf()'代表的可能不是完全相同的東西。也許最好的方法來確定問題是否真的是'clang'或架構是通過使用'gcc'在OSX上編譯它。 – Havenard