【问题标题】:How does std::cout convert numerical types to base 10?std::cout 如何将数值类型转换为以 10 为底?
【发布时间】:2020-11-17 17:33:54
【问题描述】:

我了解到诸如intlong long 之类的数字类型在C++ 中以基数为二的格式存储。可以使用按位运算符访问和修改这些单独的位。

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

总的来说,我的问题是,std::cout 是否实际上将数字从 2 转换为 10,它是如何做到的?我在这里犯了其他逻辑错误吗?

【问题讨论】:

  • 你没有转换数字本身,只是生成一个表示。对于整数,这很容易,您可能会自己弄清楚。
  • 轻微修正:您计算机中的一切都以二进制表示形式存储在内存或存储器中。字符、字符串、整数、浮点值、图像、复杂对象。如果它在内存中,则以 1 和 0 的形式存储。
  • 如何用笔和纸将 base 2 转换为 base 10?
  • 如何用笔和纸将base 10转换为base 2?就是这样。

标签: c++ binary numbers cout


【解决方案1】:

我发现 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 类型只是一个数字,当您编写一个字符时,它会在表格中查找该字符。在旧的 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

库中的 sn-p 只是在循环中执行此操作。

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2020-12-29
      • 2022-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-26
      • 2023-03-17
      • 2019-04-16
      相关资源
      最近更新 更多