2016-04-20 36 views
2

不同的結果,我有以下的C程序:C代碼宏產生使用文字VS可變

#include <stdio.h> 
#include <math.h> 

#define LOG2(x) ((int)(log((double)(x))/log(2))) 

int main() { 

    int num = 64; 
    int val1 = LOG2(num); 
    int val2 = LOG2(64); 

    printf("val1: %d, val2 %d\n", val1, val2); 

    return 0; 
} 

,其輸出:

val1: 5, val2: 6 

爲什麼這個宏時我產生不同的(和錯誤)的答案在一個變量中使用它,但是當我直接輸入64時能正常工作嗎?

不管這是否是獲取日誌庫2的好方法,是什麼導致了這種行爲?有什麼辦法可以讓這個宏與變量正常工作嗎? (我所有的輸入都是2的精確冪)

+0

對我來說,兩者都顯示'5':_http://ideone.com/QSVioZ_ –

+1

對我來說,兩者都是6.你能告訴你正在使用哪臺機器和編譯器嗎? – Harveer

+0

這個問題似乎是你在宏中轉換爲'(int)'。刪除轉換允許'LOG2'返回與聲明爲'double'的值相同的值。 –

回答

2

從數學上來說,這是計算base-2日誌的好方法,但由於log(val)和log(2)都會變長, ,這種劃分的結果不可能最終爲5.999,這將截斷爲5.我建議四捨五入,尤其是如果你知道輸入總是2的冪。

(但你爲什麼得到常量與變量的不同答案?這是一個很好的問題,我不確定答案。通常的答案是,當涉及常量時,編譯器能夠在編譯時執行一些/所有的計算,但通常編譯器最終會使用比運行時環境微妙或明顯不同的浮點算法uldn't想到,編譯器會解釋像log()功能,而這樣做的編譯時間常數摺疊。)


而且,有些C庫有一個log2()功能,應該給你完美的答案,但我不知道該功能是多麼標準。

+1

'log2'被添加到C99中 –

+1

我想補充一點,使用'round()'是一個好的解決方案(而不是滾動你自己的舍入) –