我在調試函數hashKey
。問題是它會在不同的平臺,Windows/win ce,mac os,android下爲同一輸入生成不同的結果。下面是代碼:不同平臺下的按位移運算符(windows,mac os,android)
unsigned long hashKey(const char *name,size_t len)
{
unsigned long h=(unsigned long)len;
size_t step = (len>>5)+1;
for(size_t i=len; i>=step; i-=step)
h = h^((h<<5)+(h>>2)+(unsigned long)name[i-1]);
return h;
}
這裏被測試程序使用:
int main()
{
char word[] = { 0xE6, 0xBE, 0xB3, 0xE9, 0x96, 0x80, 0xE7, 0x89, 0xB9, 0xE5,
0x88, 0xA5, 0xE8, 0xA1, 0x8C, 0xE6, 0x94, 0xBF, 0xE5, 0x8D,
0x80, 0x2E, 0x70, 0x6E, 0x67, 0x00};
// for those who are interested in what the value of variable means, it means
// "澳門特別行政區.png"
unsigned int val = hashKey(word, strlen(word));
printf("hash key for [%s] is [%d].\n", word, (unsigned int)val);
}
的長度是25時,輸入值是相同的,但是,返回值是不同的:
在android中,它是648. 在win ce中,它是96,這是期望值。
我找不出原因。任何幫助表示讚賞。提前致謝!
更多信息:後在循環,引起h>>2
幾個interations
不同值開始。所以在開始時,值是相同的。
看來ansi字符的輸入沒有這樣的問題。
5月3日解決(感謝大鏢客的意見),2013年
unsigned long hashKey(const char *name,size_t len)
{
unsigned long h=(unsigned long)len;
size_t step = (len>>5)+1;
for(size_t i=len; i>=step; i-=step)
{
unsigned long charVal = (unsigned long)name[i-1];
if (charVal >= 0x00000080)
charVal = charVal | 0xffffff80;
h = h^((h<<5 & 0xffffffe0)+(h>>2 & 0x3fffffff) + charVal);
}
return h;
}
是的,你是對的,h >> 2確實會產生不同的結果。但即使我改爲h/4,結果仍然不同... – Hunter 2013-04-28 03:03:07
有什麼解決辦法呢? – Hunter 2013-04-28 03:31:22
此代碼幾乎可能因本頁提到的任何原因而失敗。選擇更少的機器和編譯器相關的算法會更好。這就是說,看看你使用的編譯器是否支持無符號移位運算符>>>。如果他們這樣做,那麼h >>> 2不應該簽署擴展。如果該操作員不可用,那麼您可能不得不依賴位掩碼和位操作符&。例如,如果x是一個32位整數,那麼(x&0x7fffffff)是x的值,高位清零。 (x&0x3fffffff)清除兩個最高位。 – Yojimbo 2013-04-29 11:22:26