微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C-当负数始终被编码为其二进制数的2的补码时,负数字符中的有符号位-128在哪里?

如何解决C-当负数始终被编码为其二进制数的2的补码时,负数字符中的有符号位-128在哪里?

  • 我知道有符号整数中的最高有效位用于对符号进行编码。
  • 我还得到一个负整数几乎总是被编码为其二进制数的2的补码。

我无法调和上述两个事实。

如果我们看一下-128的示例,则在对它进行编码时将采取以下步骤

  1. 计算出128的等效二进制数:10000000
  2. 取1的补码:01111111
  3. 将1的补码加1可获得2的补码:10000000

我的问题是:sign bit在哪里为负整数?换句话说,我想了解如何将10000000解码为- 128而不是- 0

  1. 如果使用最左边的1(MSB)来编码-128的负号,那是否不给我们留下7位二进制0000000,其十进制等效值为0(而不是-128)?
  2. 或者,计算机(当然是数字地)(对存储在某个内存位置的负整数执行计算时)以相反的顺序执行上述步骤1-3,以解码1字节char的值认为1是最高有效位(而不是0)?
  3. 或者是对-128中的第8位(2 ^ 7)的符号和位进行MSB编码。

我已经看到了this的问题,但是我的问题有所不同,因为我非常清楚+128不能存储在1字节中,因为它的带符号二进制文件将转换为0100000000,这需要9位

解决方法

负整数的符号位在哪里?

Door #3:“或者MSB对-128中的第8位(2 ^ 7)的符号和位进行编码

具有8位带符号的char,编码为 2的补码,M为7,并且...

符号位的为-(2 M (C17dr§6.2.6.2 2)

10000000是-128 + 0 * 64 + 0 * 32 + 0 * 16 + 0 * 8 + 0 * 4 + 0 * 2 + 0 * 1-> -128

,

如果我们在这里查看-128的示例,则在存储它时将执行以下步骤……

在存储时,在计算/转换时不行。当编译器正在处理源代码中的-128时,或者当我们在纸上看到并使用它时,我们将进行所需的任何计算。我们可以根据需要使用纸上的位或数字或标记。当我们得出最终答案时,然后具有最终含义。中间步骤不必以相同的方式使用位。

给出“ 128”,我们以纯二进制(无符号)计算得出这是10000000。然后,我们可以通过将这些位补至01111111并加1(仍为纯二进制,无符号)来获得10000000,从而计算其补码表示形式。

解释该字节时,包括将其用于算术运算或从二进制补码表示转换为十进制时,高位将被解释为符号位。但是,同样,我们不需要在整个计算过程中以相同的方式使用位。我们可以取10000000,看到高位被设置为告诉我们数字为负,然后像以前一样对其进行二进制补码:将这些位补至01111111,然后再加1以得到10000000。现在我们有相同的位,但是它们是纯二进制数,没有符号。它们代表128,我们知道它是负数,因为我们较早地观察到原始符号。

还要注意,signed char xunsigned char y使用相同的位模式来表示不同的值。当x具有位模式11111111时,它表示-1。当y的位模式为11111111时,它表示255。为实现此目的,编译器将对x进行的操作与对y进行的操作使用不同的指令。使用带符号类型与使用无符号类型有不同的说明。 (它们中的许多在很大程度上重叠;加法和减法通常使用相同的指令执行,但是标志结果的解释不同,以检测溢出和其他情况。)

此外,对于此单字节示例,编译器通常不将其作为char使用。在源文本中,128是一个int常量。在内部,编译器可能会将128转换为32位int,然后将其取反以使−128变为11111111111111111111111110000000位,然后将其存储在签名的char中,取低8位10000000。(这可能因编译器而异。)

有趣的是,此边界问题确实会影响-2147483648的类型。考虑一个使用32位int和64位long的C实现。 −2,147,483,648可在32位int中表示,但是在C语法中,-2147483648不是常数,而是-2147483648的组合。并且,由于无法用32位表示2,648,因此long是常数。因此-2147483648的类型为long。您可以使用以下方法进行验证:

printf("%zu %zu\n",sizeof -2147483647,sizeof -2147483648);

它将在C实现中使用32位int打印“ 4 8”。

(这提出了INT_MIN的定义方式。它的值必须为−2,648,但类型必须为int。)

,

虽然到目前为止,补数是表示带符号整数值的最常见方法,但这不是唯一的方法,C不需要补数表示。

请注意,您不能仅用 any 表示形式中的8位表示 signed productVariations-您可以用1表示范围128 '补码或符号幅度,或二进制补码中的范围[-127..127]。因此,根据定义, 您需要8位以上的位来表示带符号的[-128...127]

128
,

对于任何使用整数值的数据类型,例如“ int”,“ short”,“ byte”,“ char”,“ long”(除“ unsigned”之外),其值范围为:(-1 * 2 总位-1))到(2 总位-1))-1 。并且最左边的位用作符号位。

对于char数据类型,其大小为1字节s号。的位是8位。 1最左边的位用于符号,剩余的位用于值。所以我们得到的没有符号的值来自

0至127,即(00000000) 2 至(01111111) 2

,当它与符号位一起时,范围为

-128至-1,即(10000000) 2 至(11111111) 2

,

确切的布局取决于计算机上的 (CPU),但取决于C上的不是。编译器是为特定计算机构建的,并且知道如何指示其处理没错。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。