繁体   English   中英

c++ 中的 8 位数字 129 怎么会存储为 -127 的有符号字符

[英]How come 129, which is 8-bit number, is stored as -127 in signed char in c++

我声明了 signed char 并在其中存储了 129,一个 8 位数字。 当将其类型转换为 integer 并打印结果时,它的 -127。 我知道它是溢出的,但是当您查看 129 的二进制即 10000001 时会发生混淆。在有符号字符中,最高有效位保留为符号位,7 位的 rest 用于存储数字的二进制。 根据这个概念,129 应该存储为 -1。 MSG代表负号,7位的rest是0000001,是1。为什么129的二进制变成-1时,129变成-127。

#include <iostream>

using namespace std;

int main() {
    char a=129;
    cout<<(int) a; // OUTPUT IS -127
    return 0;
}

你目前对负数的想法是这样的:

  • 00000001 == 1
  • 10000001 == -1
  • 01111111 == 127
  • 11111111 == -127

这意味着您只有可用的整数范围 -127...127 和
你也有两个零。 (00000000 == 0 和 10000000 == -0)

最好的方法是所谓的补码 对于任何数字 x,您否定二进制表示并加 1 以得到 -x。
它的意思是:

  • 00000001 == 1
  • 11111111 == -1
  • 01111111 == 127
  • 10000001 == -127
  • 10000000 == -128

这样,只有 00000000 为零,并且您拥有最宽的范围 -128...127。
此外,CPU 不需要额外的指令来添加有符号数,因为它与无符号数的加法和减法相同。

你可能想知道,为什么要加1。没有它,它被称为一个补码。
https://en.wikipedia.org/wiki/Ones%27_complement

当前的每台计算机都以一种称为二进制补码的格式存储低级有符号整数。

在二进制补码中,MAX_POSITIVE+1 是 MIN_NEGATIVE。

0x00000000 is 0.
0x00....0V is V.
0x01....11 is MAX_POSITIVE
0x10....00 is MIN_NEGATIVE
0x11....11 is -1.

乍一看,这看起来很奇怪。

但是,这意味着正数和负数的加法逻辑是相同的。 事实上,有符号和无符号的数学运算结果是相同的,除了在溢出时正符号数变为负数,而正无符号数的溢出环绕为 0。

请注意,在 C++ 中,溢出有符号数是未定义的行为,不是因为硬件将其捕获,而是因为通过将其设为 UB,编译器可以自由假设“将正数相加是正数”。 但是在机器代码级别,实现是 2s 补码,C++ 定义了从有符号到无符号的转换,遵循 2s 补码假设。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM