我只是好奇,为了在二进制中表示-1,是否有一个原因,使用了2的补码:翻转位并加1?

-1由11111111(2的补码)表示,而不是(对我来说更直观)10000001,10000001是二进制1,第一位为负标志。

免责声明:我的工作不依赖二进制算术!


当前回答

这是为了简化数字的和和和差。2的补数中一个负数和一个正数的和与正常方式的和是一样的。

其他回答

为什么用Two2的补语系统来表示负数,而不是用One的补语系统,一个令人满意的答案是 二的补语系统解决了一的补语系统中存在的表示负数的0的多重表示和对进位的需要。

欲了解更多信息,请访问https://en.wikipedia.org/wiki/Signed_number_representations

用于末端绕行访问 https://en.wikipedia.org/wiki/End-around_carry

维基百科说明了一切:

二补系统的优点是不需要加减电路检查操作数的符号来决定是加还是减。这一特性使系统实现更简单,能够轻松地处理更高精度的算术。此外,零只有一种表示,避免了与负零相关的微妙之处,这种微妙之处存在于补体系统中。

换句话说,无论数字是否为负,加法都是一样的。

在阅读这个问题的答案时,我看到了这条评论[编辑]。

0100(4)的补数是1100。现在1100是12如果我说正常的话。所以, 当我说标准1100时,它是12,但当我说2的补足1100时,那么 是-4?另外,在Java中,当1100(假设现在是4位)被存储时 如何确定它是+12还是-4 ?——hagrawal 7月2日16:53

在我看来,这条评论中提出的问题非常有趣,所以我想首先重新措辞,然后提供一个答案和一个例子。

系统如何确定一个或多个相邻字节必须如何解释?特别是,系统如何确定给定的字节序列是普通二进制数还是2的补数?

ANSWER -系统建立如何通过类型解释字节序列。 类型定义

需要考虑多少字节 如何解释这些字节

示例-下面我们假设

Char的长度为1字节 短的是2字节长 Int型和float型的长度是4字节

请注意,这些大小是特定于我的系统的。尽管非常常见,但它们可能因系统而异。如果您想知道它们在您的系统中是什么,请使用sizeof操作符。

首先,我们定义一个包含4个字节的数组,并将它们初始化为二进制数10111101,对应于十六进制数BD。

// BD(hexadecimal) = 10111101 (binary)
unsigned char   l_Just4Bytes[ 4 ]   =   { 0xBD, 0xBD, 0xBD, 0xBD };

然后我们使用不同的类型读取数组内容。

Unsigned char和signed char

// 10111101 as a PLAIN BINARY number equals 189
printf( "l_Just4Bytes as unsigned char  -> %hi\n", *( ( unsigned char* )l_Just4Bytes ) );

// 10111101 as a 2'S COMPLEMENT number equals -67
printf( "l_Just4Bytes as signed char    -> %i\n", *( ( signed char* )l_Just4Bytes ) );

未签名的空头和空头

// 1011110110111101 as a PLAIN BINARY number equals 48573
printf( "l_Just4Bytes as unsigned short -> %hu\n", *( ( unsigned short* )l_Just4Bytes ) );

// 1011110110111101 as a 2'S COMPLEMENT number equals -16963
printf( "l_Just4Bytes as short          -> %hi\n", *( ( short* )l_Just4Bytes ) );

Unsigned int, int和float

// 10111101101111011011110110111101 as a PLAIN BINARY number equals 3183328701
printf( "l_Just4Bytes as unsigned int   -> %u\n", *( ( unsigned int* )l_Just4Bytes ) );

// 10111101101111011011110110111101 as a 2'S COMPLEMENT number equals -1111638595
printf( "l_Just4Bytes as int            -> %i\n", *( ( int* )l_Just4Bytes ) );

// 10111101101111011011110110111101 as a IEEE 754 SINGLE-PRECISION number equals -0.092647
printf( "l_Just4Bytes as float          -> %f\n", *( ( float* )l_Just4Bytes ) );

内存中的4个字节(l_Just4Bytes[0..]3)始终保持完全相同。唯一改变的是我们如何理解它们。

同样,我们告诉系统如何通过类型来解释它们。

例如,上面我们使用了以下类型来解释l_Just4Bytes数组的内容

无符号字符:纯二进制的1字节 有符号字符:2的补码中的1字节 无符号短:2字节的纯二进制表示法 短:2字节的2补码 Unsigned int: 4字节的纯二进制表示法 Int: 4字节的2的补码 float:在IEEE 754单精度表示法中为4字节


[编辑]这篇文章是在user4581301的评论后编辑的。谢谢你抽出时间来写这些有用的句子!

有不同类型的表示,它们是:

无符号数表示 有符号数字表示 补体表示 二补体表示法

无符号数字表示,仅用于表示正数

有符号的数字表示,用来表示正数和负数。在有符号数表示中,MSB位表示符号位,其余位表示数字。当MSB为0时表示数字为正,当MSB为1时表示数字为负。

有符号数表示的问题是0有两个值。

补码表示法的问题是0有两个值。

但如果我们使用2的补体表示,那么0就只有一个值,这就是为什么我们用2的补体形式表示负数。

来源:负数为什么以二进制补码形式存储

这是为了简化数字的和和和差。2的补数中一个负数和一个正数的和与正常方式的和是一样的。