小朋友學演算法(6) 求冪pow函式的四種實現方式

2021-08-20 11:37:14 字數 3681 閱讀 1506

在math.h中,宣告了乙個函式pow(x, n),用於求x的n次方。假如咱們不呼叫math.h中的pow函式,如何實現求x ^ n的演算法呢?

#include

double

pow1

(double x,

unsigned

int n)

return res;

}int

main()

執行結果:

2 ^ 10 = 1024.000000

5 ^ 3 = 125.000000

10 ^ 0 = 1.000000

#include

double

pow2

(double x,

unsigned

int n)if(

1== n)

return x *

pow2

(x, n -1)

;}intmain()

上面三種方法都有乙個缺點,就是迴圈次數多,效率不高。舉個例子:

3 ^ 19 = 3 * 3 * 3 * … * 3

直接乘要做18次乘法。但事實上可以這樣做,先求出3的2^k次冪:

3 ^ 2 = 3 * 3

3 ^ 4 = (3 ^ 2) * (3 ^ 2)

3 ^ 8 = (3 ^ 4) * (3 ^ 4)

3 ^ 16 = (3 ^ 8) * (3 ^ 8)

再相乘:

3 ^ 19 = 3 ^ (16 + 2 + 1) = (3 ^ 16) * (3 ^ 2) * 3

這樣只要做7次乘法就可以得到結果。

我們發現,把19轉為2進製數:10011,其各位就是要乘的數。這提示我們利用求二進位制位的演算法,所以就可以寫出下面的**:

#include

double

pow3

(double x,

int n)

n >>=1;

x *= x;

}return res;

}int

main()

執行結果:

2 ^ 10 = 1024.000000

5 ^ 3 = 125.000000

10 ^ 0 = 1.000000

3 ^ 19 = 1162261467.000000

#include

double

pow4

(double x,

unsigned

int n)if(

1== n)

double tmp =

(n &1)

? x :1;

return tmp *

pow4

(x * x, n /2)

;}intmain()

#include

#include

#include

using

namespace std;

#define count 100000000

double

pow1

(double x,

unsigned

int n)

return res;

}double

pow2

(double x,

unsigned

int n)if(

1== n)

return x *

pow2

(x, n -1)

;}double

pow3

(double x,

int n)

n >>=1;

x *= x;

}return res;

}double

pow4

(double x,

unsigned

int n)if(

1== n)

double tmp =

(n &1)

? x :1;

return tmp *

pow4

(x * x, n /2)

;}intmain()

endtime =

clock()

;printf

("呼叫系統函式計算1億次,執行時間%d毫秒\n"

,(endtime - starttime));

starttime =

clock()

;for

(int i =

0; i < count; i++

) endtime =

clock()

;printf

("呼叫pow1函式計算1億次,執行時間%d毫秒\n"

,(endtime - starttime));

starttime =

clock()

;for

(int i =

0; i < count; i++

) endtime =

clock()

;printf

("呼叫pow2函式計算1億次,執行時間%d毫秒\n"

,(endtime - starttime));

starttime =

clock()

;for

(int i =

0; i < count; i++

) endtime =

clock()

;printf

("呼叫pow3函式計算1億次,執行時間%d毫秒\n"

,(endtime - starttime));

starttime =

clock()

;for

(int i =

0; i < count; i++

) endtime =

clock()

;printf

("呼叫pow4函式計算1億次,執行時間%d毫秒\n"

,(endtime - starttime));

return0;

}

執行結果:

呼叫系統函式計算1億次,執行時間222毫秒

呼叫pow1函式計算1億次,執行時間790804毫秒

呼叫pow2函式計算1億次,執行時間89706毫秒

呼叫pow3函式計算1億次,執行時間3320毫秒

呼叫pow4函式計算1億次,執行時間6874毫秒

從執行結果可以看出來,最快的是math.h提供的函式pow,接下來依次是pow3、pow4、 pow2,最慢的是pow1。

在網路上找到了乙份微軟的math.h原始碼 ,這裡有關於pow函式的實現

template

<

class

_ty>

inline _ty _pow_int

(_ty _x,

int _y)

}

這個實現思路跟pow3的實現思路是類似的。

在實際程式設計時,可以直接呼叫math.h提供的pow函式;如果在特定場合需要自己定義的話,推薦使用pow4的方式。

小朋友學Python(4) 縮排

學習 python 與其他語言最大的區別就是,python 的 塊不使用大括號 來控制類,函式以及其他邏輯判斷。python 最具特色的就是用縮進來寫模組。縮排的空白數量是可變的,但是所有 塊語句必須包含相同的縮排空白數量,這個必須嚴格執行 if true print true else print...

小朋友學Python(16) 模組

python 模組 module 是乙個 python 檔案,以 py 結尾,包含了 python 物件定義和python語句。模組讓你能夠有邏輯地組織你的 python 段。把相關的 分配到乙個模組裡能讓你的 更好用,更易懂。模組能定義函式,類和變數,模組裡也能包含可執行的 def print i...

小朋友學十大排序演算法(1) 氣泡排序

將相鄰兩個數比較,將大的調到後頭。如果有n個數,則要進行n 1趟比較。在第1趟中要進行n 1次兩兩比較,在第j趟比較中要進行n j次兩兩比較。上圖中有5個數,要進行5 1 4趟比較。第1趟,要進行n 1 4次兩兩比較 第2趟,要進行5 2 3次兩兩比較 第3趟,要進行5 3 2次兩兩比較 第4趟,要...