Task: Negative base numbers




Go: package main

import (
    "fmt"
    "log"
    "strings"
)

const digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"

func reverse(bs []byte) []byte {
    for i, j := 0, len(bs)-1; i < len(bs)/2; i, j = i+1, j-1 {
        bs[i], bs[j] = bs[j], bs[i]
    }
    return bs
}

func encodeNegBase(n, b int64) (string, error) {
    if b < -62 || b > -1 {
        return "", fmt.Errorf("base must be between -62 and -1 inclusive")
    }
    if n == 0 {
        return "0", nil
    }
    var out []byte
    for n != 0 {
        rem := n % b
        n /= b
        if rem < 0 {
            n++
            rem -= b
        }
        out = append(out, digits[int(rem)])
    }
    reverse(out)
    return string(out), nil
}

func decodeNegBase(ns string, b int64) (int64, error) {
    if b < -62 || b > -1 {
        return 0, fmt.Errorf("base must be between -62 and -1 inclusive")
    }
    if ns == "0" {
        return 0, nil
    }
    total := int64(0)
    bb := int64(1)
    bs := []byte(ns)
    reverse(bs)
    for _, c := range bs {
        total += int64(strings.IndexByte(digits, c)) * bb
        bb *= b
    }
    return total, nil
}

func main() {
    numbers := []int64{10, 146, 15, -942, 1488588316238}
    bases := []int64{-2, -3, -10, -62, -62}
    for i := 0; i < len(numbers); i++ {
        n := numbers[i]
        b := bases[i]
        ns, err := encodeNegBase(n, b)
        if err != nil {
            log.Fatal(err)
        }
        fmt.Printf("%13d encoded in base %-3d = %s\n", n, b, ns)
        n, err = decodeNegBase(ns, b)
        if err != nil {
            log.Fatal(err)
        }
        fmt.Printf("%13s decoded in base %-3d = %d\n\n", ns, b, n)
    }
}





VB: Const DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
Dim Str(63) As String
Private Function mod2(a As Long, b As Integer) As Long
    mod2 = a - (a \ b) * b
End Function
Private Function swap(a As String, b As String)
    Dim t As String
    t = a
    a = b
    b = t
End Function
Private Function EncodeNegativeBase(ByVal n As Long, base As Integer) As String
    Dim ptr, idx As Long
    Dim rem_ As Long
    Dim result As String
    If base > -1 Or base < -62 Then
        EncodeNegativeBase = result
    Else
        If n = 0 Then
            EncodeNegativeBase = "0"
        Else
            ptr = 0
            Do While n <> 0
                rem_ = mod2(n, base)
                n = n \ base
                If rem_ < 0 Then
                    n = n + 1
                    rem_ = rem_ - base
                End If
                result = result & Mid(DIGITS, rem_ + 1, 1)
            Loop
        End If
    End If
    EncodeNegativeBase = StrReverse(result)
End Function
Private Function DecodeNegativeBase(ns As String, base As Integer) As Long
    Dim total As Long, bb As Long
    Dim i As Integer, j As Integer
    If base < -62 Or base > -1 Then DecodeNegativeBase = 0
    If Mid(ns, 1, 1) = 0 Or (Mid(ns, 1, 1) = "0" And Mid(ns, 2, 1) = 0) Then DecodeNegativeBase = 0
    i = Len(ns)
    total = 0
    bb = 1
    Do While i >= 1
        j = InStr(1, DIGITS, Mid(ns, i, 1), vbTextCompare) - 1
        total = total + j * bb
        bb = bb * base
        i = i - 1
    Loop
    DecodeNegativeBase = total
End Function
Private Sub Driver(n As Long, b As Integer)
    Dim ns As String
    Dim p As Long
    ns = EncodeNegativeBase(n, b)
    Debug.Print CStr(n); " encoded in base "; b; " = "; ns
    p = DecodeNegativeBase(ns, b)
    Debug.Print ns; " decoded in base "; b; " = "; p
    Debug.Print
End Sub
Public Sub main()
    Driver 10, -2
    Driver 146, -3
    Driver 15, -10
    Driver 118492, -62
End Sub