超过机器整数范围时,仍然可以逐位计算

业务标识有时以很长的十进制文本存在。如果先强制转成机器整数,再进行其他进制转换,可能在真正处理之前就失去原值。

可以先检查每一位是否属于允许的数字,再以文本或逐位缓冲保存数值。这样后续计算处理的是数字序列,容量边界由输入上限和可用资源决定,而不是某个整数类型的位数。

进制转换并不要求把整个输入先放进一个固定宽度整数。对于很长的十进制文本,可以把它看成一列数字,用小范围的余数和商逐位处理。每个中间步骤只涉及一位数字与有限余数,因此不会随着整串数字变长而立刻溢出。

这条路线特别适合需要保留任意长度整数的编码工具。它解决的是整数表达转换,不处理小数点、负号或科学计数法;这些内容应在进入核心转换之前被明确拒绝或单独拆分。

一次长除法,产生一个商和一个余数

十进制数字串除以目标基数,示例使用 16Python
digits = "12345678901234567890"
base, remainder, quotient = 16, 0, []
for char in digits:
    value = remainder * 10 + (ord(char) - ord("0"))
    quotient.append(str(value // base))
    remainder = value % base
q = "".join(quotient).lstrip("0") or "0"
assert q == "771604931327160493"
assert remainder == 2

在这个片段里,remainder 始终小于目标基数。每次引入一个十进制数字,value 的范围也就有明确上限。注意它假设输入已经逐字符校验为 ASCII 数字,不能把减去字符零的操作当成校验本身。

商的每一位仍然按十进制组织。开头的零可以统一去除,但结果为零时需要保留一个零,避免用空字符串同时表示零值和没有结果。

重复取余,最后反转输出顺序

一条直接的路线是逐位计算商与余数,反复缩短尚未处理的数值。每轮产生的输出片段先暂存,完成后再按目标顺序组织起来。

零值与前导零应提前统一,否则它们可能在循环终止、输出长度和往返验证中产生特殊分支。中间结果的容量也需要单独检查,不能只限制最终输出。

用任意精度整数做独立参考值,而非作为原生实现前提Python
alphabet = "0123456789ABCDEF"
number = 12345678901234567890
parts = []
while number:
    number, remainder = divmod(number, 16)
    parts.append(alphabet[remainder])
encoded = "".join(reversed(parts)) or "0"
assert encoded == "AB54A98CEB1F0AD2"

字符串算法中,每次用上一轮得到的商继续长除法,余数映射成目标字符。余数从最低位开始出现,所以完成后需要反转。上面的 Python 示例依靠内置大整数提供参考结果,便于核对原生逐位算法是否正确。

目标字符表必须固定且没有重复字符。对于包含大小写字母的高进制编码,大小写通常具有不同数值,不能在输入阶段随意全部转小写。字符表顺序变化也会改变所有结果,需要作为格式版本的一部分维护。

反方向使用乘基数、加下一位

从目标进制恢复十进制时,可以按高位到低位扫描。每读一位,将当前十进制数字串乘以基数,再加上该位的数值。乘法和加法都通过十进制列上的进位完成,不需要固定宽度的完整整数容器。

这两种方向的算法都可能随着输入长度增长而增加明显的计算量。不限数值范围不等于不限输入规模,应该限制最大字符数,并在构造输出前考虑最坏长度。对频繁处理极大整数的场景,再评估成熟的大整数库是否更合适。

几类输入值得单独规定
输入建议约定
零统一输出一个零字符
前导零保留含义但规范化表达
负号由外层解析,核心只处理绝对值
未知字符拒绝整份输入
过长数字在计算前拒绝

不要在出现非法字符时只返回已经转换的前缀。这样的结果看起来像一个正常整数,调用方很难意识到尾部从未参与计算。失败应与零值清楚区分。

用双向性质验证超长输入

更高进制可以让数字标识更紧凑,但只是改变表示方式。它并不会自然隐藏业务规模,也不替代访问权限检查。

验收时可以从零、小值和带前导零的输入开始,再加入超过常见整数范围的文本。将结果解码回规范化后的原值,比仅检查输出包含哪些字符更能说明转换正确。

除了已知答案,还可以检查:规范化后的十进制输入,编码再解码应恢复原值;目标进制文本解码再编码,应得到约定的规范形式。前导零被主动去除时,需要比较数值含义而不是原始字节完全一致。

测试长度应跨过机器整数上限,而不只选很小的数字。再加入全为最大数字的输入,观察连续进位是否正确;加入只有一个零和大量前导零的输入,检查循环是否能够正常结束。

如果业务只是缩短普通范围内的编号,固定宽度整数实现通常更简单。只有当输入范围确实超过它,或协议明确允许长整数时,才需要承担逐位大数处理的额外成本。