计算2对数字的称赞

时间:2016-03-21 11:25:18

标签: c binary

我正在努力将60转换成2的补码。这就是我的方式:

60 to binary   00111100
1's compliment 11000011
2's compliment 11000100 (by adding 1 to the 1's compliment)

当我使用以下代码

在程序中执行此操作时
#define NUM 60
unsigned char c;
c=~NUM;
printf("%d",c);

它打印195而不是196。请解释一下这背后的原因?还解释了任何给定数字的计算(〜)的过程。

4 个答案:

答案 0 :(得分:2)

表达式*str++不是严格可移植的。要计算您的补码,您可以尝试从~NUM减去,例如:UCHAR_MAX。这可以移植,因为according to the standard, UCHAR_MAX is required to be a binary power minus one

  

c = UCHAR_MAX - NUM;应等于2 CHAR_BIT - 1.

不要忘记随后增加UCHAR_MAX,就像在纸上的最后一步:c

你可以安全地在一个步骤中执行整个二进制补码操作,假设您的表示的基础选择是无符号的(它应该是,因为二进制补码的整个想法是表示无符号位组上的有符号整数): c++。这是因为使用the following procedure also described within the C11 standard将负数转换为无符号类型:

  

...如果新类型是无符号的,则通过重复加或减一个可以在新类型中表示的最大值来转换该值,直到该值在新类型的范围内。

在这种情况下,重复恰好一次c = -NUM; -60 + UCHAR_MAX + 1 == 196。如果我们讨论的是更大的值,例如UCHAR_MAX == 255,则需要多次此类添加。

就此而言,如果您需要对-32767的数字大于32768进行操作,则您需要考虑不同的后缀,例如NUM就足够了,比#define NUM 32768L大得多。

答案 1 :(得分:1)

运营商~执行逻辑不回馈1的补充,而不是2补。 要在C中执行2的补码,请使用-一元减号。请参阅以下示例:

#define NUM 60
char c1 = ~NUM;    //1's complement
char c2 = -NUM;    //2's complement
printf("NUM=%d, 1's complement=%d, 2's complement=%d\n",NUM, c1, c2);

但重点是你无法在无符号类型上执行2的补码,因为默认情况下2的补码用于查找相同的表示形式负数。即2 -2,10 -10,5 -5等。
请考虑您要查找的值是否定(2' s补码)值的无符号表示。即中加入:

printf("2's complementunsigned representation=%d\n", (unsigned char)c2);

将打印196,即-60,读取为无符号值。

答案 2 :(得分:0)

符号〜计算数字的1的补码。你只需要在计算中加1。

c = ~NUM + 1;

您对计算1的补码过程的描述是正确的。要了解更多信息,请访问wiki page on 1's complement

干杯!

答案 3 :(得分:0)

〜给你一个补充。使用否定( - )来获得两个补码。

#include <stdio.h>

#define NUM0 0
#define NUM60 60

int main() {
   unsigned char b;
   unsigned char c;

   b = ~NUM0;
   c = -NUM0;

   printf( "b=%d c=%d", b, c );

   b = ~NUM60;
   c = -NUM60;

   printf( "b=%d c=%d", b, c );
}

输出: b = 255 c = 0 b = 195 c = 196