十进制转换有点慢,但实际上并没有复杂得多。让我们看一下十六进制转换,更像是我们可能会用真实代码编写它。举例来说,在 C++ 中,您可能会执行如下转换:
char digits[] = "0123456789abcdef";
std::string result;
int input = 0xFA20;
while (input) {
int digit = input & 0xf; // or: digit = input % 0xf;
input >>= 4; // or: input /= 16;
result.push_front(digits[digit]);
}
然而,现在,这有一些神奇的数字。让我们摆脱它们:
const int base = 16;
while (input) {
int digit = input % (base - 1);
input /= base;
result.push_front(digits[digit]);
}
在摆脱这些神奇数字的过程中,我们还使例程几乎通用——如果我们更改 'base' 的值,例程的其余部分仍然有效,并将输入转换为指定的基数。本质上,如果我们想要支持大于 16 的碱基,我们需要做的唯一其他更改就是在“digits”数组中添加更多内容。
为了简单起见,这也忽略了一些事情。最明显的是,如果数字是负数,您通常设置一个标志,转换为一个正数,最后如果设置了标志,则在字符串中放入一个“-”)。对于 2 的补码,最大负数有一个极端情况,它不能转换为正数(不转换为具有更大范围的类型)。通常,您通过提升大多数类型来处理这个问题。对于您最大的整数类型(您无法提升),通常最容易硬编码该值。
原则上,浮点数并没有太大的不同——你基本上仍然会进行数学运算来一次生成一个数字。事实上,它变得更加复杂仅仅是因为您通常必须处理几种不同的格式(至少是“基本”浮点和某种“科学”格式),以及字段宽度和精度的变量。当你处理完这个问题时,你最终会得到大约几百行代码——这不是一个特别离谱的数量,但在这里包含可能有点超出了意义。