【问题标题】:C++ and unsigned typesC++ 和无符号类型
【发布时间】:2018-07-01 02:41:11
【问题描述】:

我在看C++ Primer 5th Edition,下面的部分看不懂:

在无符号类型中,所有位都表示值。例如,一个 8 位 unsigned char 可以保存从 0 到 255 的值。

“所有位代表值”是什么意思?

【问题讨论】:

  • 就像你手上的所有手指代表你的整个手一样。
  • 我想这个说法是不正确的。在有符号和无符号类型中,所有位都表示值。例如,8 位可以表示 256 个唯一值,无论类型是有符号还是无符号。
  • 这意味着变量中包含的所有位都可以设置不同,设置或未设置的位的每个组合对应一个不同的值。因此,更改任何位都会更改值或(相反地)更改值意味着至少有一位已更改。注意:该语句是错误的,因为它暗示这仅适用于无符号类型,但也适用于其他一些类型。
  • @S.M.这个声明是关于无符号类型的,它没有说明有符号类型,所以我不确定你如何认为它不正确
  • 别担心你的英语,你的问题很清楚,措辞很好。如果其他一切都写得好,这里的人们会很乐意帮助语法和拼写。

标签: c++ unsigned bit-representation


【解决方案1】:

您应该将此与signed 类型进行比较。在signed 值中,一位(最高位)用于指示该值是正数还是负数,而其余位用于保存该值。

【讨论】:

  • 这是signed 整数的一种可能实现,但这在现实世界中非常罕见。它被称为补码。包括 x86、ARM、MIPS、POWER 和 SPARC 在内的真实系统都使用二进制补码,但事实并非如此。
  • @MSalters 所有 3 个允许的表示形式的最高位是符号位,1 是负数;并且在所有情况下,其他位都保存该值(表示不同的是位设置对应于哪些值)
  • @M.M:“符号位”实现的 -1 等于 1000...1,即值 X 和 -X 仅在一个位上不同,而 其他位 编码abs(X)。二进制补码没有符号位; 所有位都有一个特定的值。最高位恰好是唯一具有负值的位。
  • @MSalters 您正在描述符号幅度表示。术语“符号位”是指在所有 3 种表示中都持有符号的位
  • @MSalters 当我看到二进制补码数的最高位是1 时,我知道它是负数。然后我反转所有位,将结果加一,并得到负值。我的描述特别避免说 1 与 2 的补码,因为在两个系统中,最高位是符号指示符,而其余位是值 - 你只需要以不同的方式解释它们。
【解决方案2】:

普通可复制类型对象的值由其中的某些位决定,而其他位不影响其值。在 C++ 标准中,不影响值的位称为 填充位

例如考虑一个8位的类型,其中最后4位是填充位,那么00000000和00001111所代表的对象具有相同的值,比较相等。

实际上,填充位通常用于alignment 和/或error detection

知道了上面的知识,就可以明白书上说的是什么了。它说无符号类型没有填充位。但是,这个说法是错误的。事实上,标准只保证unsigned char(和signed charchar)没有填充位。以下是标准[basic.fundamental]/1相关部分的引用:

对于窄字符类型,对象表示的所有位都参与值表示。

此外,C11 标准 6.2.6.2/1 说

对于 unsigned char 以外的无符号整数类型,对象表示的位应分为两组:值位和填充位(后者不需要任何一个)。

【讨论】:

    【解决方案3】:

    这意味着所有 8 位代表一个实际值,而在 signed 字符中只有 7 位代表实际值,第 8 位(最高有效位)代表该值的符号 - 正或负(+/-)。

    【讨论】:

    • 不是真的。在进行基本算术时,硬件不会以特殊方式处理最高位。有符号数仍然使用所有位。它仍然有256个州。有符号/无符号更多的是关于数字代表的范围。上位并不特别。当它是一个签名号码时,恰好会告诉你这个标志。
    • @William 这正是我的答案。
    • 从表面上看,你所说的都是错误的。 -1 在设置了最高位的情况下不是 1。 (0x81) 有符号字符不是带符号位的七位数字。将其视为 8 位有符号数字会更有帮助。 -1 + 1 为零,因此我们知道 -1 是所有位设置,因为当我们将 1 添加到它时,我们得到零。 (0xFF + 0x01 = 0x00) 有趣的是,所有设置了最高位的数字都是负数。但它不是一个七位数的符号。
    【解决方案4】:

    例如,一个字节包含8位,所有8位都用于从0开始计数。

    对于无符号,所有位 0 = 00000000 表示 0, 00000001 = 1, 00000010 = 2, 00000011 = 3, ... 直到 11111111 = 255。
    对于有符号字节(或有符号字符),最左边的位表示符号,因此不能用于计数。 (我在光学上分离最左边的位!)0 0000001 = 1,但 1 0000001 = -1、0 0000010 = 2 和 1 0000010 = -2 等等,直到 0 1111111 = 127 和 1 1111111 = -127。在本例中,1 0000000 表示 -0,表示无用/浪费,因此可以表示例如 128。

    还有其他方法可以将位编码为数字,有些计算机从左侧开始而不是从右侧开始。这些细节是特定于硬件的,与理解“无符号”无关,你只需要在你想用单个位弄乱代码时关心这一点(不推荐)。

    【讨论】:

    • ... 除了符号幅度编码几乎从不用于整数,仅用于浮点
    【解决方案5】:

    这主要是理论上的事情。在真实硬件上,signed 整数也是如此。显然,对于有符号整数,其中一些值是负数。

    回到unsigned - 文中所说的基本上是无符号数的值只是 1signed 整数不是这种情况。因此,如果您需要位掩码,它必须是足够宽的unsigned 类型,否则您可能会遇到无效的位模式。

    【讨论】:

      猜你喜欢
      • 2018-08-14
      • 2019-06-10
      • 1970-01-01
      • 2012-01-23
      • 1970-01-01
      • 2013-02-06
      • 1970-01-01
      • 2014-02-01
      • 2012-07-31
      相关资源
      最近更新 更多