user6048670
user6048670

Reputation: 2887

How can I convert a ulong to an positive int?

I have a piece of code that is

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

and the problem is that it's sometimes returning negative values. I know the reason is because (int)result can be negative. But I want to coerce it to be non-negative since it's used as an index. Now I realize I could do

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

but is there a better way?

On a deeper level, why is int used for the index of containers in C#? I come from a C++ background and we have size_t which is an unsigned integral type. That makes more sense to me.

Upvotes: 2

Views: 1192

Answers (2)

Tim S.
Tim S.

Reputation: 56536

While you can find a way to cast this to an int properly, I'm wondering why you don't just calculate it as an int from the beginning.

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;

As to why C# uses a signed int for indexes, it has to do with cross-language compatibility.

Upvotes: 1

NineBerry
NineBerry

Reputation: 28499

Use

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

As you sum up values you reach a positive integer number that cannot be expressed as a positive number in a signed 32 bit integer. The cast to int will return a negative number. The modulo operation will then also return a negative number. If you do the modulo operation first, you will get a low positive number and the cast to int will do no harm.

Upvotes: 2

Related Questions