2016-04-10 28 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