2012-12-31 49 views
-1
#include<stdio.h> 
#include<math.h> 

int main() { 
double n,p,ans; 
while(scanf("%lf %lf",&n,&p)==2) 
{ 
    ans=pow(p,(1/n)); 

    printf("%.0lf\n",ans); 
} 
return 0; 
} 

什麼算法是用來尋找ANS here.what是這個POW()函數的複雜性?什麼算法用於POW()函數在C

+5

它可能取決於數學庫的實現 - 不能保證GNU數學庫使用的是與Microsoft編譯器或Intel等一樣的。 – maerics

+0

閱讀源代碼,Luke。 – mah

+0

我保證這不是我的作業。 –

回答

6

C99標準第4.12.7.4已經沒什麼可說的莫過於以下的pow功能:

Synopsys公司

#include <math.h> 
double pow(double x, double y); 
float powf(float x, float y); 
long double powl(long double x, long double y); 

說明

pow函數計算x上升到功率y。如果x是有限且負數,並且y有限且不是整數值,則會發生域錯誤。範圍錯誤可能會發生。如果x爲零且y爲零,則可能會出現域錯誤。如果x爲零且y小於零,則可能會出現域錯誤或範圍錯誤。

返回

pow函數返回[xy]。

請注意,沒有關於函數複雜性的信息,也沒有關於要使用的算法的預期。這是因爲在C的某些實現中,函數可能是處理器本身的,而在其他體系結構中,浮點處理不是由硬件提供的。

你可以假設,雖然,複雜性並不比的log,乘法和exp結合更糟:

double pow(double x, double y) { 
    return exp(log(x)*y); 
} 

在與FP單元多的平臺,以e爲基數冪,浮點乘法,而自然對數全部取O(1)時間,所以pow也應該如此。

-edit2-我不太清楚explog的複雜性,但我認爲實現使用泰勒近似和一堆查找表。那仍然會給O(1)

+0

但是exp(log(x)* y)不能用O(1)時間計算,因爲log(x)應該乘以y次; –

+2

在FP單元的許多架構上,FP乘法應該是'O(1)'。在這些情況下,乘法是在硬件中實現的並且需要固定的週期數。請記住,這不是一個*精確*整數計算,而是一個*近似*浮點計算。 – 2012-12-31 18:32:23

0

正如前面的回答所說,不可能說。

在x86,可以實現它使用fyl2x其計算(Y *的log 2(X)),並且f2xm1指令

fld1   1.0 
fld    y 
fld    x 
fyl2x     // y * log2(x) 
fadd     // add 1.0 
f2xm1     // 2^(x-1) 

[用1.0沿]然後在一個處理器沒有或很少支持浮點單元中的exp/log指令,log和exp可能使用seeries方程進行計算,根據輸入值和方程的好壞,可能需要5-20次迭代。

我認爲在這種情況下O(1)的複雜性仍然很重要,但我相信我們可以想出它不會像那樣工作的場景。

+0

'pow'通常不是用迭代算法實現的。大多數商業圖書館使用準備的極小極大多項式,以及其他專門技術。多項式可能有許多項,但可能不會多達20個。一個着名的庫「crlibm」可能使用可變數量的「迭代」,因爲在它的某些函數實現中,它會執行一個評估,進行測試,然後在必要時進行更廣泛的評估。我記得,我看到了這一些更簡單的功能。我不知道'crlibm'已經征服了'pow'。 –

+0

是的,但實際上假設寫圖書館的人確實知道他們在做什麼 - 雖然我確信幾乎所有的商業圖書館都是好的東西的副本,或者原本很好的東西,但C庫中不能保證說明是這種情況。我的觀點是,它是一個「你不能說,除非你看在特定情況下使用的特定圖書館的來源」。 –

+0

對於常見的C/C++工具鏈,通常通過迭代計算pow(double,int),如相關頭文件所示。對於pow(double,double),通常的方法是通過由極小多項式提供的核心近似值通過對數加冪運算(無迭代)的變體。這些多項式的程度在很大程度上取決於參數減少的執行方式;在該表中使用的表的大小與多項式的複雜度之間存在折衷。專業編寫數學圖書館的人(全部五十人左右:-)通常都很清楚他們在做什麼。 – njuffa