main()的 { char a,b,c; 一个= 6; B = 1-5; c = a + b; printf(“%d%d%d \ n”,a,b,c); }
Here , what actually happens 00000110 10000101 -------- 10000111 -------- So values c will -11 , then how come it is 1.
答案 0 :(得分:6)
您的错误是:2的补码中的-5不是10000101
。在32位中,它是:11111111111111111111111111111011
6,是:
00000000000000000000000000000110
总和是:
11111111111111111111111111111011
+ 00000000000000000000000000000110
--------------------------------
00000000000000000000000000000001
我建议您阅读有关签名号码表示的this Wikipedia page。现代CPU使用两个补码。
答案 1 :(得分:6)
似乎你混淆了2的补码和符号位的概念,以及C中的按位或加法。
(谁会期望6 +( - 5)≠1 ......)
在大多数架构中,负数被实现为其大小的2's complement。虽然C标准没有强制使用2的补码,但它是最受欢迎的。在2的补码中,x
的负数被构造为~x + 1
,例如
5 = 0000 0101
~5 = 1111 1010 # ~x means 1's complement, a.k.a. bitwise-NOT
~5+1 = 1111 1011 # +1 means add 1 to the integer.
这是-5的二进制表示。整数的最高位称为符号位,因为它确定整数的符号。 2的补码中的所有负整数都有符号位= 1. 但只是翻转符号位并不会否定数字。这只是指示数字是否为负数。
+
表示C和所有其他实用语言中的整数加法,因为整数加法比按位或更有用。因此,虽然OR在逻辑证明中被广泛编写为+
,但是没有编程语言可以识别+
用于按位OR。
在C中,char
只是一个有符号整数,正好是1个字节长。行为与所有其他类型的有符号整数相同。您必须使用|
进行按位OR。
0000 0110 0000 0110
+ 1000 0101 | 1000 0101
——————————— ———————————
1000 1011 1000 0111
^^--- note the carry ---^^
答案 2 :(得分:2)
#include<stdio.h>
main()
{
char a,b,c;
a=6;
b=-5;
c=a+b;
printf("%d %d %d \n", a,b,c);
}
/*
*
* Here 6 value as = 00000110
* -5 value will be treated as complement of 5.
*
* Actual 5 value is 00000101
* Complement of 5 is 11111010
* Then we need to add 1 to the complement of 5
* So that time value is 11111011
*
* Now we need to add 5 and 6
*
* 00000110
* 11111011
---------
00000001
*/
答案 3 :(得分:2)
您似乎对负值如何存储在计算机上有点困惑。你在那里所谓的“标志和数量”。由于符号和幅度数字的运算很困难(正如您所经历的那样!),基本上所有计算机都使用“二进制补码”。这可以通过以下两个步骤轻松计算:
这样做,0000101
变为1111011
(为简单起见,为8位)。然后添加很容易:
1111011 = -5
+ 0000110 = 6
________ |
0000001 = 1
如预期的那样是1。
答案 4 :(得分:1)
根据你的例子:
Char为1字节表示8位(bbbb bbbb)
二进制6是
0000 0110
二进制5是
0000 0101
对于-5我们将获得2的赞美5,所以2的赞美是5
1111 1011
二进制加法:
0000 0101
1111 1011
---------
0000 0001
---------
0000 0001 Which is equal to 1 hence proved :)