【问题标题】:How numbers are stored? [closed]数字是如何存储的? [关闭]
【发布时间】:2014-02-05 05:40:37
【问题描述】:

编译器使用什么样的方法来存储数字?一个字符是 0-255。并排的两个字符是 0-255255。在 c++ 中,一个短是 2 个字节。大小为 0-65535。现在,编译器如何将 255255 转换为 65535 以及无符号数中的 - 会发生什么?

【问题讨论】:

标签: c++


【解决方案1】:

您可以存储在 n 位中的最大值(当最小值为 0 并且表示的值是连续范围时)是 2ⁿ − 1。对于 8 位,这给出了 255。对于 16 位,这给出了 65535。

您的错误是认为您可以将 255 与 255 连接以获得两个 chars 中的最大值 - 这绝对是错误的。相反,要从 8 位的范围(即 256)到 16 位的范围,您将执行 256 × 256 = 65536。由于我们的第一个值为 0,因此最大值再次为 65535。

请注意,char 只保证至少 8 位,short 至少有 16 位(并且必须至少与char 一样大)。

【讨论】:

  • char 保证有 8 位。我见过 9 位 char,听说一些现代机器有 16 位或 32 位 char
  • @JamesKanze 出于某种原因,我认为 CHAR_BIT 必须正好是 8,即使它与 USHRT_MAX 在同一个“等于或大于”列表中。谢谢。
  • 也不能保证(unsigned char 除外)所有位都参与该值。在至少一台机器上(仍在生产中),int 是 48 位,但只使用了 40 位。
  • 您认为他们如何在 36 位机器上实现 C 和 C++。 (我认为最后的 36 位机器几年前就停产了,但它们过去很常见。)
  • @JamesKanze 但是必须至少有足够多的位参与该值才能满足最小最大值要求。
【解决方案2】:

当使用十进制系统时,一位数字的范围是 0-9,两位数字的范围是 0-99。使用十六进制系统时同样适用,但您必须在十六进制系统中进行数学运算。一个十六进制数字的范围是 0-Fh,两个十六进制数字(一个字节)的范围是 0-FFh。两个字节的范围是0-FFFFh,十进制转换为0-65535。

【讨论】:

  • +1 捕捉他们可能在想什么。
【解决方案3】:

十进制是一个以 10 为底的数字系统。这意味着从右到左的每个连续数字代表 10 的增量幂。例如,1233 + (2*10) + (1*100)。在日常生活中你可能不会这样想,但它就是这样工作的。

现在您将相同的概念从十进制 (base-10) 转换为二进制 (base-2),现在每个连续的数字都是 2 的幂,而不是 10。所以 11000 + (0*2) + (1*4) + (1*8)

现在让我们取一个 8 位数字 (char);这个数字有 8 位数字,所以最大值是 255 (2**8 - 1),或者其他方式,11111111 == 1 + (1*2) + (1*4) + (1*8) + (1*16) + (1*32) + (1*64) + (1*128)

当还有 8 位可用于生成 16 位值时,您只需继续计算 2 的幂;你不只是将两个255s“粘”在一起来制作255255。所以最大值是65535,或者其他方式,1111111111111111 == 1 + (1*2) + (1*4) + (1*8) + (1*16) + (1*32) + (1*64) + (1*128) + (1*256) + (1*512) + (1*1024) + (1*2048) + (1*4096) + (1*8192) + (1*16384) + (1*32768)

【讨论】:

    【解决方案4】:

    取决于类型:整数类型必须存储为二进制 (或者至少对 C++ 程序来说是这样),所以你有一点 每个二进制数字。除了极少数例外,所有位都是 显着(虽然这不是必需的,并且有 至少一台机器在int 中有额外的位)。在 一台典型的机器,char 将是 8 位,如果不是 有符号,可以存储[0,2^8)范围内的值;换一种说法, 介于 0 和 255(含)之间。 unsigned short 将是 16 位 (范围[0,2^16)),unsigned int 32 位(范围[0,2^32)) 和 unsigned long 32 位或 64 位。

    对于带符号的值,您必须至少使用其中一个 符号位,减少最大正值。这 负值的准确表示可能会有所不同,但在大多数情况下 机器,它将是 2 的补码,因此范围将是 signed char:[-2^7,2^7-1)`等

    如果你不熟悉基础二,我建议你学习它 很快;它是所有现代机器存储方式的基础 数字。您还应该了解 2 的补码: 通常的人类表示称为符号加幅度,并且是 在计算机中非常罕见。

    【讨论】:

      【解决方案5】:

      你的数学完全错了。这就是它的真实情况

      由于每个位只能呈现两种状态之一(1 和 0),因此 n 位作为一个整体可以代表 2^n 个不同的 数量 而不是数字。在处理整数时,2 字节的标准短整数大小可以表示 2^n - 1(n=16 所以 65535),为了计算简单,它们在现实生活中映射到十进制数。
      处理 2 个字符时,它们是两个单独的实体(字符串是字符数组)。有很多方法可以整体读取两个字符,如果您读取的是字符串,那么它将与并排的两个单独字符相同。让我举个例子:
      请记住,为简单起见,我将使用十六进制表示法!
      如果您对将 ASCII 字符映射为十六进制有疑问,请查看 ascii to hex

      为简单起见,我们假设存储在两个相邻位置的字符都是 A。
      现在 A 的十六进制代码是 0x41,所以内存看起来像

      1 个字节.......第二个字节
      01000100 01000001

      如果您要从内存中将其作为字符串读取并打印出来,那么输出将是
      AA

      如果您要将整个 2 个字节作为整数读取,那么这将表示

      0 * 2^15 + 1 * 2^14 + 0 * 2^13 + 0 * 2^12 + 0 * 2^11 + 1 * 2^10 + 0 * 2^9 + 0 * 2^8 + 0 * 2^7 + 1 * 2^6 + 0 * 2^5 + 0 * 2^4 + 0 * 2^3 + 0 * 2^2 + 0 * 2^1 + 1 * 2^0

      = 17537

      如果使用无符号整数,那么我会将 2 个字节的数据映射到之间的整数 0 和 65535,但如果相同表示有符号值,则尽管范围保持不变,但可以表示的最大正数将是 32767。值将介于 -32768 和 32767 之间,这是因为所有 2 个字节都不能被使用,并留下最高位来确定符号。 1代表阴性,2代表阳性。

      您还必须注意,类型转换(将两个字符读取为单个整数)可能并不总是给您想要的结果,尤其是当您缩小范围时。 (例如将双精度浮点数转换为整数。)



      有关更多信息,请参阅此答案double to int
      希望这会有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-11-30
        • 2012-06-28
        • 2019-05-15
        • 2011-04-21
        • 1970-01-01
        • 2012-09-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多