3

I'm overriding getting a hash code. There's a point where

Hash = 1210600964 * 31 + -837896230

which causes an OverflowException. Is there a method that I can use, something like:

Hash = addUnsafe(multiplyUnsafe(1210600964, 31), -837896230)

Without needing to link my project to another assembly? I do not want to remove overflow checks. dllimports are OK.

Joseph Nields
  • 5,527
  • 2
  • 32
  • 48
  • possible duplicate of [Overriding GetHashCode in VB without checked/unchecked keyword support?](http://stackoverflow.com/questions/4654227/overriding-gethashcode-in-vb-without-checked-unchecked-keyword-support) – sstan Jul 15 '15 at 17:11
  • @sstan no, this is asking for a system API that allows unsafe arithmetic. – Joseph Nields Jul 15 '15 at 17:33
  • by unsafe, I assume you mean that you want your code to allow arithmetic overflows without throwing an exception, right? If so, then that's what the C# keyword `unchecked` accomplishes, but that VB.NET doesn't have native support for. The thread I linked provides ways around that limitation in VB.NET. Let me know if I'm misunderstanding you. – sstan Jul 15 '15 at 17:38

1 Answers1

4

You can do the maths with 64-bit numbers instead and then use And to cut off any excess:

Option Infer On
' .....
Shared Function MultiplyWithTruncate(a As Integer, b As Integer) As Integer
    Dim x = CLng(a) * CLng(b)
    Return CInt(x And &HFFFFFFFF)
End Function

Although, as you can mix C# and VB.NET projects in one solution, it might be easiest to write a class in C# to do the unchecked arithmetic, even if you are not keen on adding a reference to another assembly.

It might even be a good idea to write the functions in C# too so that you can test that the VB functions return the expected values. It's what I did to check the above code.

Edit: I was prompted by Joseph Nields' comment to test for performance, and it turned out using CLng instead of Convert.ToInt64 and And works faster.

Andrew Morton
  • 24,203
  • 9
  • 60
  • 84
  • 2
    It might just be easier to define `Const mask = &HFFFFFFFF` and return `CInt(x And mask)` which will always fit in `Int32` – Joseph Nields Jul 15 '15 at 19:16
  • 1
    This solution did not work for me, an OverflowException was still raised. &HFFFFFFFF is -1 for signed integers. Using &H7FFFFFFF (aka Integer.MaxValue) worked, though. – Crusha K. Rool Jun 18 '17 at 13:37