關於衡量計算操作的方法:
當為算法統計操作的數量的時候,所有的C運算符被認為是一樣的操作。中間過程不被寫入隨機存儲器(RAM)而不被計算,當然,這種操作數的計算方法,只是作為那些接近機器指令和CPU運行時間的服務。所有的操作被假設成花相同的運行時間,事實上是不正確的。有很多不同的因素決定一個系統能多快運行一段樣例代碼,例如:緩存大小,內存帶寬,指令集合等等……。最后,建立一套標准才是衡量一種方法快過另一種方法的最好方法。
判斷一個整數的符號:
int v; // v為我們要判斷的整數 int sign; // 保存結果 sign = -(v < 0); // if v < 0 sign= -1, else 0. //或者為了避免在cpu上判斷而使用寄存器 sign = -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1)); // CHAR_BIT 是每字節的位數 (通常為 8). //或者為了減少指令(但不輕便) sign = v >> (sizeof(int) * CHAR_BIT - 1);
測試代碼:
#include<stdio.h> #include<math.h> #include<string.h> #include<ctype.h> #include<limits.h> int test(int v) { //正數返回0,負數返回-1 int sign; sign = -(v < 0); sign = -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1)); // CHAR_BIT 是每字節的位數 (通常為 8). sign = v >> (sizeof(int) * CHAR_BIT - 1); return sign; } int main() { int v; scanf("%d",&v); printf("%d\n",test(v)); getchar(); getchar(); return 0; }
評估一下上面最后一個語句:sign = v >> 31 for 32-bit integers,這是一個比常規操作:sign = -(v < 0).更快的方法,這種技巧可行是因為:當有符號整數右移,最左邊的位被復制到其他位,最左邊的位是1說明這個整數是負數,否則為0則為正數。當所有的位是1的時候返回-1,但是這種行為是面向特定的結構。
又或者你更加喜歡返回的結果為-1或+1,於是有了下面的表達方式:
ign = +1 | (v >> (sizeof(int) * CHAR_BIT - 1)); // 假如v < 0 返回-1, 否則返回 +1
再或者你偏愛結果返回形式是-1,0,+1,可以使用下列表現形式:
sign = (v != 0) | -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1)); //或者速度更快,但是不輕便 sign = (v != 0) | (v >> (sizeof(int) * CHAR_BIT - 1)); // -1, 0, or +1 // 或者輕便、簡潔但是也許速度不快 sign = (v > 0) - (v < 0); // -1, 0, or +1
可能你想知道數字是否非負,結果返回值為:+1或者0,於是可以使用sign = 1 ^ ((unsigned int)v >> (sizeof(int) * CHAR_BIT - 1)); // 如果 v < 0 返回 0, 否則返回 1