2016-04-10 37 views
2

BenBir ulong'u nasıl pozitif int dönüştürebilirim?

// 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; 

olan bir kod parçası var ve problem bazen negatif değerler dönen olması. Nedeni biliyorum çünkü (int)result negatif olabilir. Ama endeks olarak kullanıldığından, negatif olmayan olmaya zorlamak istiyorum. Şimdi farkettim ki,

Ancak daha iyi bir yol var mı?

Daha derin bir düzeyde neden C# içinde kapsayıcılar dizini için int kullanılır? C++ arkaplanından geliyorum ve imzasız bir integral tip olan size_t var. Bu bana daha mantıklı geliyor.

+2

Niçin 'int' için' '' '' '' '' '' '' '' ''; Gerekirse 'Buckets.Count '' yerine' ulong 'yazın. Bu, sizi 31 bitlik aralıkla sınırlayacaktır, ancak en azından düzgün bir şekilde çalışıyor :) Daha derin sorularınız için, dizinler mutlaka .NET'te sıfır temelli değildir. -10'dan +10'a uzanan bir diziye sahip olmak tamamen yasal. – Luaan

cevap

2

Kullanım

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

Eğer imzalı 32 bitlik tamsayı pozitif sayı olarak ifade edilemeyen bir pozitif tam sayı ulaşmak değerleri Özetle şöyle. Int için cast negatif bir sayı döndürür. Modulo işlemi daha sonra bir negatif sayı da verecektir. Önce modulo işlemini yaparsanız, düşük bir pozitif sayı alırsınız ve int için cast hiçbir zarar vermez.

+0

FYI, 'Buckets.Count' bir' int'dir – user6048670

1

Bunu bir int'a doğru bir şekilde yayınlamanın bir yolunu bulabilirken, neden en baştan bir int olarak hesapladığınızı merak ediyorum. C# indeksleri için imzalı int kullanır neden , bu has to do with cross-language compatibility gelince

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; 

.