Reputation: 72626
I have found a strange situation converting a piece of code from C# to VB.NET, the code is a small class that convert from base 10 to base 36 and vice versa.
the key point is this function :
/// <summary>
/// A Base36 De- and Encoder
/// </summary>
public static class Base36
{
private const string CharList = "0123456789abcdefghijklmnopqrstuvwxyz";
/// <summary>
/// Encode the given number into a Base36 string
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static String Encode(long input)
{
if (input < 0) throw new ArgumentOutOfRangeException("input", input, "input cannot be negative");
char[] clistarr = CharList.ToCharArray();
var result = new Stack<char>();
while (input != 0)
{
result.Push(clistarr[input % 36]);
input /= 36;
}
return new string(result.ToArray());
}
that converted in VB.NET should result in :
Public NotInheritable Class Base36
Private Sub New()
End Sub
Private Const CharList As String = "0123456789abcdefghijklmnopqrstuvwxyz"
''' <summary>
''' Encode the given number into a Base36 string
''' </summary>
''' <param name="input"></param>
''' <returns></returns>
Public Shared Function Encode(input As Int64) As String
If input < 0 Then
Throw New ArgumentOutOfRangeException("input", input, "input cannot be negative")
End If
Dim clistarr As Char() = CharList.ToCharArray()
Dim result = New Stack(Of Char)()
While input <> 0
result.Push(clistarr(input Mod 36))
input /= 36
End While
Return New String(result.ToArray())
End Function
The problem is that the modulo operator in VB.NET perform differently that the % remainder operator in C#, in fact if you call the encode method in C# :
long l = 13072113072399;
string result = Base36.Encode(l); //Result is : 4mt8um0b3
while calling the method in C# :
Dim l As Int64 = 13072113072399
Dim result As String = Base36.Encode(l) //Result is : 5nujsu3ar
The responsible of the difference is the different result that the modulo operator return in some situations, why ?
What is the equivalent of the % remainder operator in VB.NET ?
Upvotes: 0
Views: 2273
Reputation: 224857
The Mod
operator:
clistarr(input Mod 36)
But the actual issue is
input /= 36
In C#, /
is integer division when used on two int
s. In VB.NET, /
is Double
on Integer
s and it uses bankers’ rounding. Change it to integer division:
input \= 36
Or use DivMod
properly:
input = Math.DivRem(input, 36, remainder)
Upvotes: 4