简体   繁体   中英

Remainder operator in C# perform different than MOD in Visual Basic

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 ?

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM