2017-02-06 44 views
4

我所遇到的一些舊代碼,計算數值權衡(-0.5 *的std ::日誌(X))

double y = 1/std::sqrt(x); 

使用:

constexpr double base16 = 16.0; 
double log_base16 = std::log(base16); 
double y = std::pow(base16, -0.5 * std::log(x)/log_base16); 

基本上是:

double y = std::exp(-0.5 * std::log(x)); 

有什麼理由對於數值的好處(如準確性或更有可能避免下溢/過流程)之間的方法?原作者可能會這樣想。

+1

可以多大? 'constexpr'在2011年得到了標準化。 – Potatoswatter

+0

@Patatoswatte我清理了語法,使得例子儘可能清晰。 – keith

回答

2

原代碼被認爲是非常調皮的確,特別是在現代C++標準和IEEE754浮點:由IEEE標準要求

的std ::開方是準確的。 [原文如此]

此外,std::pow具有沒有這樣的要求。

因此我會試圖將它改寫爲1/std::sqrt(x),當然是測試。

參考:http://en.cppreference.com/w/cpp/numeric/math/sqrt

+0

請注意,「確切」可以以一定的價格出現。理論上可能的是,替代代碼更快。這就是說,這是非常理論的。唯一的快速對數是基數2和它的權力,並且對於求冪運算也是如此。 '2 ^(log2(x)/ 2)'可能比舊代碼快很多。 – MSalters

+0

@ MSalters當然,xor會更快,但是對於大多數值來說不太準確。 – Yakk

+0

@Yakk:簡寫爲'std :: exp2(std :: log2(x)/ 2))' – MSalters

0

我看不到實現的sqrt()戰俘而言什麼特別好的原因()和log()。這可能是sqrt()的實現中存在一個bug,這被用作解決方法。

一般來說,我預計這個實現會更慢,更不精確。

+1

鑑於'1/std :: sqrt(x)',我敢肯定我們可以假設'x> 0' – MSalters