2009-12-03 101 views
3

我在移植一些C++代碼的Java的中間,我一直跨實例運行在那裏誰寫它一直在做下面的除法和乘法的特殊的順序:原因在C++

double c = (1.0/(a+1.0)*pow(b, a+1.0)); 
double d = (1./(integral(gamma, dmax)-integral(gamma, dmin)))*(integral(gamma+1, dmax)-integral(gamma+1, dmin)); 

相反的:

double c = pow(b, a+1.0)/(a+1.0); 
double d = (integral(gamma+1, dmax)-integral(gamma+1, dmin))/(integral(gamma, dmax)-integral(gamma, dmin)); 

第二個看起來更清晰,除非我錯了有關C這樣的操作順序++他們應該做同樣的事情。有沒有理由做第一次而不是第二次?我能想到的唯一事情就是精確的一些奇怪的情況。

回答

6

是的,它們是一樣的。我能想到的唯一理由是數學清晰:有時,當你進行歸一化量,你經常寫:

answer = (1/total) * (some of it) 

例如,柯西積分定理經常寫

f(a) = (1/(2*pi*i)) * integral(f(z)/(z-a), dz) 
2

如果a遺體和b正在改變(例如,如果你的代碼在一個循環中,並且很明顯a在兩次迭代之間不會改變,例如因爲它是const變量),那麼原始版本可以更快地執行,因爲乘法比(假設編譯器m計算出環路中的1/...)。

這似乎是一個錯誤的優化嘗試,如果這是原因,但並不意味着它不是。

哦,關於精確度,原始版本實際上比您的精確度略低,如果有的話,因爲1/...還有一個額外的舍入誤差。正是這個四捨五入的錯誤,阻止了編譯器將你的版本轉換成它自己的意志的原始版本:它們不計算完全相同的東西(但非常接近的東西)。

1

是的,他們應該做同樣的事情。原作者可能一直在複製等式發現其他地方