关于位运算符的疑惑
本帖最后由 C++太极门小弟子 于 2021-10-11 20:14 编辑有以下例子:
a=60;
printf("%d",~a)
结果是-61
根据按位取反,a的二进制形式为00111100,按位取反后为11000011
而-61是11000011取反+1的结果
为什么取反后还需要求补码呢,而不是取反结果本身作为原码的值(卡在这里了)
问题2:
a=60
printf("%d",a<<2)
同一个数,a的二进制左移两位后为11110000,同样首位为1,为什么这个数不用取反+1(即求补码)? 本帖最后由 jackz007 于 2021-10-11 00:02 编辑
60 = 0x3c 0011 1100
~ 0x3c = 0xc3 1100 0011
195 = 0xc3 1100 0011
signed char 的正值范围是 0 ~ 127,195 > 127,超出正值的范围,应该是个负值。
195 - 256 = -61
60 = 0x3c 0011 1100
0x3c << 2 = 0xf0 1111 0000
240 = 0xf0 1111 0000
signed char 的正值范围是 0 ~ 127,240 > 127,超出正值的范围,应该是个负值。
240 - 256 = -16 jackz007 发表于 2021-10-10 23:53
请问为什么数据类型是signed char 呢
而且a<<2输出的结果是240这个-16是怎么来的 同问 这个很好理解的,60的二进制取反,然后化十进制的时候会减一化十,
负数的十进制转换是
1,化二进制,不看那负号直接化二进制。
2,取反(如果编译器int类型是2字节是8位,如果int类型是4字节是32位)
3,然后加1,就得到了补码。
那么相反负数的二进制化十进制呢,就是把刚刚的步骤反过来就行。
1,补码减1,得到反码
2,反码取反,得到了二进制
3,二进制化十进制就可以了(注意化了十进制记得带上负号)
~60就是60的二进制取反之后,计算机以为是负数(注意:二进制的第一位是符号位),
然后化十进制,现在计算机是以为是补码,补码化十进制要经过
1,补码减1,得到反码
2,反码取反,得到了二进制
3,二进制化十进制就可以了(注意化了十进制记得带上负号)
如果还看不懂的话,那你来我这,我1对1辅导了。
{:10_256:} {:10_256:} 谢谢 暂时还没学到位运算符,我也不会,抱歉 泌阳 发表于 2021-10-11 23:50
这个很好理解的,60的二进制取反,然后化十进制的时候会减一化十,
负数的十进制转换是
1,化二进制,不 ...
就是为什么认为取反后的是补码而不是原码{:10_266:} 因为取反之后第一位二进制也参与运算,第一位是符号位,所以计算机把他当作补码来存储。输出时要转换的。
C++太极门小弟子 发表于 2021-10-12 23:08
就是为什么认为取反后的是补码而不是原码
你懂了没
jackz007 发表于 2021-10-10 23:53
你这回答是错的,别误导人家。OK? 进来看解答的 C++太极门小弟子 发表于 2021-10-11 17:59
请问为什么数据类型是signed char 呢
而且a
有点不理解你的问题,能用比较详细的说明一下吗?
泌阳 发表于 2021-10-12 23:19
有点不理解你的问题,能用比较详细的说明一下吗?
就是第二个问题左移两位之后第一位符号数也是1为什么就不用减一取反呢 C++太极门小弟子 发表于 2021-10-12 23:33
就是第二个问题左移两位之后第一位符号数也是1为什么就不用减一取反呢
定义的类型是什么
泌阳 发表于 2021-10-12 23:14
你懂了没
啊我好像搞错了,取反是对60的补码取反而不是对原码取反,所以计算机认为取反后的是补码,然后再进行减一取反,是这么操作的对吗 C++太极门小弟子 发表于 2021-10-12 23:44
啊我好像搞错了,取反是对60的补码取反而不是对原码取反,所以计算机认为取反后的是补码,然后再进行减一 ...
是源码取反为反码,反码加一就是补码。
泌阳 发表于 2021-10-12 23:41
定义的类型是什么
类型是Int