std::cout 如何将数值类型转换为以 10 为基数?

How does std::cout convert numerical types to base 10?

我了解到 intlong long 等数值类型在 C++ 中以二进制格式存储。可以使用按位运算符访问和修改这些单独的位。

但是,我最近想知道为什么数字也没有从 std::cout 以 2 为底数打印到屏幕上,并且认为它们在打印之前一定已经转换为以 10 为底数。换句话说,由于 std::cout 以 10 进制输出这些数字,我认为必须进行一些转换过程才能将这些数字从 2 进制转换为 10 进制。

总的来说,我的问题是,std::cout 是否真的将数字从 2 进制转换为 10 进制,它是如何转换的?我在这里犯了其他一些逻辑错误吗?

我发现 libstdc++(gcc 的标准库)源代码几乎无法导航,但我认为它的主要部分在这里完成:

https://github.com/gcc-mirror/gcc/blob/8e8f6434760cfe2a1c6c9644181189fdb4d987bb/libstdc%2B%2B-v3/include/bits/locale_facets.tcc#L794

这似乎对十进制数字使用了很好的“除以 10 并打印余数”技术:

do
  {
    *--__buf = __lit[(__v % 10) + __num_base::_S_odigits];
    __v /= 10;
  }
while (__v != 0);

要稍微分解一下,请记住 char 类型只是一个数字,当您写一个 char 时,它会在 table 中查找字符。在旧的 ASCII 和新的 UTF-8 字符编码中,'0' 是 48,'1' 是 49,'2' 是 50 等等。这非常方便,因为您可以打印任何数字 0 -9 通过将其添加到“0”:

putchar('0' + 3) // prints 3

因此,要得到每个数字,除以 10,余数是最后一位:

int x = 123;
putchar('0' + (x % 10)) // prints '0' + 3, or '3'
x = x / 10;             // x = 12
putchar('0' + (x % 10)) // prints '0' + 2, or '2'
x = x / 10;             // x = 1
putchar('0' + (x % 10)) // prints '0' + 1, or '1'
x = x / 10;             // x = 0, stop

库中的代码片段只是循环执行此操作。

您会注意到代码向后打印数字。这就是为什么库中的代码片段会在每个迭代器 (*--__buf = ...) 中递减字符指针 - 它从右侧开始并从右到左反向打印。

不要纠结于在计算机中的表示方式。没关系。要将 value 转换为以 10 为基数的表示形式,只需一次选择一个数字。 value 除以 10 的余数是 10 进制表示中的最低位。要取出所有数字,只需继续取余数即可:

while (value != 0) {
    std::cout << value % 10;
    value = value / 10;
}

打印出 value 的 base-10 表示中的数字。要构建 value 的字符串表示形式,请将每个数字转换为字符(通过添加 ’[=11=]’)并将字符存储到数组中。如果你从右到左存储字符(最自然的方式),你必须记住之后要反转它们。如果您从左到右存储它们,它们的顺序就会正确。