1. 程式人生 > >int abs(int n)實現對比

int abs(int n)實現對比

ACM模版

abs()函式對比

在C\C++的<math.h>和<cmath>中均有abs的實現,而今天心血來潮,另外手動實現了兩個abs()函式,用來做一下對比,一種是通過關係運算符判斷正負求解,一種是通過位運算求解,仔細看哦,很值得回味的測試……(PS:為了增大區別,每個函式的運算次數為MAXN次)。

#include <cstdio>
#include <iostream>
#include <ctime>
#include <cmath>

using namespace std;

const int MAXN = 1000000
; int abs_1(int n) { if (n < 0) { return -n; } else { return n; } } int abs_2(int n) { return (n ^ (n >> 31)) - (n >> 31); } int main() { int a, b = 0; while (cin >> a) { // 系統abs()函式測試 long long start = clock(); for
(int i = 0; i < MAXN; i++) { b = abs(a); } long long end = clock(); cout << "abs() : " << a << ' ' << b << ' ' << end - start << '\n'; // 判斷正負abs()函式實現 start = clock(); for (int i = 0; i < MAXN; i++) { b = abs_1(a); } end = clock(); cout
<< "abs_1() : " << a << ' ' << b << ' ' << end - start << '\n'; // 位運算abs()函式實現 start = clock(); for (int i = 0; i < MAXN; i++) { b = abs_2(a); } end = clock(); cout << "abs_2() : " << a << ' ' << b << ' ' << end - start << '\n'; } return 0; }

經過多次測試,發現時間差距還是挺明顯的,當然對於一次abs()而言,差距可以視為沒有吧,當然這麼說不太嚴謹。

描述

根據資料我們不難發現,abs_1()abs_2()對於正負數的處理時間差別還是挺大的,但是令人好奇的是<cmath>中abs()對於正負數的處理時間卻幾乎相等,至於為什麼,就麻煩好奇心比我強的人去挖掘原始碼吧,然後告訴我怎麼實現的。

接著呢,我想abs_1()不用分析了,有腦子的都看得懂,而對於位運算搞定的abs_2()來說,可讀性真的不算高,對於不經常和位運算打交道的人而言,挺繞的。首先我們定義的是4個位元組的32位2進位制有符號整形,也就是int型,原諒我把一個整形形容的那麼複雜,好了,言歸正傳,因為有符號,所以我們知道第32位是符號位,所以n>>31最後得到的就是符號位的值,如果是負數,結果為-1,反之則為0。那麼如果n為正數,n^0-0=n,而如果為負數,n^(-1)的結果也就是|n|-1,所以最後再-(-1)也就是n的絕對值了,我想這裡不用過多解釋,直接用一組資料寫寫畫畫就知道了,真的不知道,那就麻煩你去看看位運算了,因為今天關鍵不是要搞位運算,所以,我還是不會解釋,畢竟我是一個懶人。

由於閒著也是數星星、數羊,於是我又進行了一個測試,測試<cmath>與<math.h>中abs()的區別,上面的資料已經有了前者的測試結果,所以鑑於我懶,我只再給出<math.h>的測試資料。

描述

雖然和前邊的資料對比感覺不明顯,但是還是有些許區別的,我認為<math.h>的要比<cmath>的abs()穩定性差些。大概這就是為什麼C++推薦使用的標頭檔案是<cmath>,而<math.h>只是為了相容。

當然,以上所有測試資料都是基於我的機子,我的測試樣本,也許有的地方不夠準確,那麼我只能將其歸咎於我的失責,但是一貫喜歡找客觀原因的我會告訴你:測試樣本不夠大,測試樣本分佈不夠均勻。但是,懶惰的我,從不會因為知道這些就去重測,因為,現在都三點了,我還有線代沒看/(ㄒoㄒ)/~~,看過線代後還要看會兒程式碼大全……如果非要說我不夠嚴謹,沒有治學精神,那麼我也不得不承認,畢竟這種放大了一百萬倍後產生的差別還如此甚微的,真的沒有太大錙銖必較的價值。

測試了這麼大會兒,雖然測試資料上有些不夠嚴謹,但是我們基本上可以得出,位運算是最牛逼的!!!對於某種特定的需求,這裡的確可以產生可見的優化。

最後,跟上一句,倒數第三段是在浪費你們時間,我只是給自己找一個隨性一些的藉口,當然,這一段也是廢話。