我正在努力将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
。请解释一下这背后的原因?还解释了任何给定数字的计算(〜)的过程。
答案 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