2016-04-10 86 views
2

我有一段代碼,如何將ulong轉換爲正整數?

// Bernstein hash 
// http://www.eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx   
ulong result = (ulong)s[0]; 
for (int i = 1; i < s.Length; ++i) 
{ 
    result = 33 * result + (ulong)s[i]; 
} 
return (int)result % Buckets.Count; 

,問題是,它有時會返回負值。我知道原因是因爲(int)result可能是負面的。但我想強制它是非負的,因爲它被用作索引。現在我知道我可以做

int k = (int)result % Buckets.Count; 
k = k < 0 ? k*-1 : k; 
return k; 

但是有沒有更好的方法?

在更深層次上,爲什麼使用int作爲C#中容器的索引?我來自C++背景,我們有size_t這是一個無符號整型。這對我來說更有意義。

+2

爲什麼在鑄造到'int'之前不要執行'%'?如有必要,可以將'Buckets.Count'轉換爲'ulong'。這仍然會將你限制在31位範圍內,但至少它能正常工作:)至於更深層次的問題,在.NET中,索引不一定是基於零的。擁有從-10到+10的數組是完全合法的。 – Luaan

回答

2

使用

return (int)(result % (ulong)Buckets.Count); 

當你總結一下你達到這個不能表示爲32位有符號整數正數的正整數數值。轉換爲int將返回一個負數。模操作將返回一個負數。如果你首先進行模運算,你會得到一個低的正數,而對int的投射不會造成傷害。

+0

僅供參考,'Buckets.Count'是一個'int' – user6048670

1

雖然您可以找到一種方法將其正確投射到int,但我想知道您爲什麼不從一開始就將其計算爲int

int result = (int)s[0]; // or, if s[0] is already an int, omit the cast 
for (int i = 1; i < s.Length; ++i) 
{ 
    result = 33 * result + (int)s[i]; 
} 
return Math.Abs(result) % Buckets.Count; 

至於爲什麼 C#使用了索引的簽署int,它has to do with cross-language compatibility