Task: Negative base numbers

C: #include <stdio.h>

const char DIGITS[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
const int DIGITS_LEN = 64;

void encodeNegativeBase(long n, long base, char *out) {
    char *ptr = out;

    if (base > -1 || base < -62) {
        
        out = "";
        return;
    }
    if (n == 0) {
        
        out = "0";
        return;
    }

    
    while (n != 0) {
        long rem = n % base;
        n = n / base;
        if (rem < 0) {
            n++;
            rem = rem - base;
        }
        *ptr = DIGITS[rem];
        ptr++;
    }
    *ptr = 0;

    
    ptr--;
    while (out < ptr) {
        char t = *out;
        *out = *ptr;
        *ptr = t;
        out++;
        ptr--;
    }
    return;
}

long decodeNegativeBase(const char* ns, long base) {
    long value, bb;
    int i;
    const char *ptr;

    if (base < -62 || base > -1) {
        
        return 0;
    }
    if (ns[0] == 0 || (ns[0] == '0' && ns[1] == 0)) {
        
        return 0;
    }

    
    ptr = ns;
    while (*ptr != 0) {
        ptr++;
    }

    
    value = 0;
    bb = 1;
    ptr--;
    while (ptr >= ns) {
        for (i = 0; i < DIGITS_LEN; i++) {
            if (*ptr == DIGITS[i]) {
                value = value + i * bb;
                bb = bb * base;
                break;
            }
        }
        ptr--;
    }

    return value;
}

void driver(long n, long b) {
    char buf[64];
    long value;

    encodeNegativeBase(n, b, buf);
    printf("%12d encoded in base %3d = %12s\n", n, b, buf);

    value = decodeNegativeBase(buf, b);
    printf("%12s decoded in base %3d = %12d\n", buf, b, value);

    printf("\n");
}

int main() {
    driver(10, -2);
    driver(146, -3);
    driver(15, -10);
    driver(12, -62);

    return 0;
}


C++: #include <iomanip>
#include <iostream>
#include <tuple>
#include <vector>

const std::string DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

std::string encodeNegativeBase(int64_t n, int b) {
    if (b < -62 || b > -1) {
        throw std::runtime_error("Argument out of range: b");
    }
    if (n == 0) {
        return "0";
    }

    std::string output;
    int64_t nn = n;
    while (nn != 0) {
        int rem = nn % b;
        nn /= b;
        if (rem < 0) {
            nn++;
            rem -= b;
        }
        output += DIGITS[rem];
    }

    std::reverse(output.begin(), output.end());
    return output;
}

int64_t decodeNegativeBase(const std::string& ns, int b) {
    if (b < -62 || b > -1) {
        throw std::runtime_error("Argument out of range: b");
    }
    if (ns == "0") {
        return 0;
    }

    int64_t total = 0;
    int64_t bb = 1;

    for (auto it = ns.crbegin(); it != ns.crend(); it = std::next(it)) {
        auto ptr = std::find(DIGITS.cbegin(), DIGITS.cend(), *it);
        if (ptr != DIGITS.cend()) {
            auto idx = ptr - DIGITS.cbegin();
            total += idx * bb;
        }
        bb *= b;
    }
    return total;
}

int main() {
    using namespace std;

    vector<pair<int64_t, int>> nbl({
        make_pair(10, -2),
        make_pair(146, -3),
        make_pair(15, -10),
        make_pair(142961, -62)
        });

    for (auto& p : nbl) {
        string ns = encodeNegativeBase(p.first, p.second);
        cout << setw(12) << p.first << " encoded in base " << setw(3) << p.second << " = " << ns.c_str() << endl;

        int64_t n = decodeNegativeBase(ns, p.second);
        cout << setw(12) << ns.c_str() << " decoded in base " << setw(3) << p.second << " = " << n << endl;

        cout << endl;
    }

    return 0;
}