将十进制转换为平衡的七廿五进制。

4
我正在尝试编写一个函数,将十进制转换为平衡七廿五进制(0123456789ABCDEFGHKMNPRTVXZ),其中0表示-13,D:0,Z:13。
我已经尝试过这个函数,但有些情况无法正常工作。
static const std::string HEPT_CHARS = "0123456789ABCDEFGHKMNPRTVXZ";

std::string heptEnc(int value){
    std::string result = "";

    do {
        int pos = value % 27;
        result = std::string(HEPT_CHARS[(pos + 13)%27] + result);
        value = value / 27;
    } while (value != 0);

    return result;
}

在这个例子中,-14、-15、14和15都不能正常工作。
call(x) - expect: result
heptEnc(-9841) - 000: 000
heptEnc(-15) - CX: 
heptEnc(-14) - CZ: 
heptEnc(-13) - 0: 0
heptEnc(-1) - C: C
heptEnc(0) - D: D
heptEnc(1) - E: E
heptEnc(13) - Z: Z
heptEnc(14) - E0: 0
heptEnc(15) - E1: 1
heptEnc(9841) - ZZZ: ZZZ 

1
你应该得到什么值?你尝试过调试你的程序了吗? - Some programmer dude
1
预期值在冒号之前,所以我期望 E0,但我只得到了 0。我编辑了帖子以指定我的语法。 - Jeremy Talus
1
算法可能不正确。(-15) % 27 == -15,然后您访问负偏移量的 HEPT_CHARS - Igor Tandetnik
如果value == 14,你需要得到2个数字,但是value = value / 27;这行代码不正确,因为循环在第一个数字后就会停止。 - mch
@mchjust弄明白了,试图绕过这个问题。 - Jeremy Talus
2个回答

3

刚才搞定了,这是代码:

static const std::string HEPT_CHARS = "0123456789ABCDEFGHKMNPRTVXZ";

inline int modulo(int a, int b) 
{
    const int result = a % b;
    return result >= 0 ? result : result + b;
}

std::string heptEnc(int value)
{
    std::string result = "";

    do {
        int pos = value%27;
        result = std::string(HEPT_CHARS[modulo(pos + 13,27)] + result);
        value = (value+pos) / 27;
    } while (value != 0);

    return result;
}

显然,数学取模、C++取模以及修改更新值的方式的混合使用起到了奇效。


确实是一个数学技巧,因为我进行计算和纸质工作,所以我的计算器使用的是数学模运算,而不是C++的模运算。无论如何,谢谢。 - Jeremy Talus

1
您正在错误地使用模(%)运算符。难以确定signed int最初将被设置为什么值。请改用以下方法:
unsigned int uvalue = std::abs(value);
unsigned int upos = uvalue % 27;
int pos = static_cast<int>(upos) - 13;

当然,您需要单独处理转换的符号:
int sign = value >= 0 ? 1 : -1;

实际上这不是符号的问题,更多是围绕value = value / 27;的问题。问题在于平衡系统,因为0表示-13,Z表示+13,所以E0可以被解读为27 + -13,因此它是14。 - Jeremy Talus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接