一、首先你得知道计算机数据存储形式
我们都知道计算机存储底层都是二进制单位,二进制就是:数据只用0和1两个号码表示存储。
二进制正负数的表示方法有三种: 原码,反码和补码。
正数的三个码都是一样的。负数不一样,下边有解释。它们都是以补码形式存储的。
short为例
1字节=8位,short类型在c语言中占2个字节,那么一个short类型的数据在内存中就占用16位。
比如c语言中short类型,9用二进制表示:0000 0000 0000 1001
而short可表示的10进制数字范围是:- 2^15 到 2^15-1 。这是因为其中有1位(最高位)用来表示符号,最高位为1时表示负数,最高位为0时表示正数。
0111 1111 1111 1111 这样就是表示最大的正数为2^15-1。
负数三个码表示方式与正数不同,例如-9,
-9 原码:1000 0000 0000 1001
补码:1111 1111 1111 0111(根据原码取反(符号位不变)加1计算而来)
所以-9在内存中存在的二进制为:1111 1111 1111 0111
按理说补码为1000 0000 0000 0001的时候就表示最小值了,它的原码是1111 1111 1111 1111,计算出的10进制数为-2^15-1。这就有问题了,明明可以表示到2^15的,还差一个数啊,下边给你解释,考虑过0吗?0怎么表示,-0怎么表示?
0在内存中表示为:0000 0000 0000 0000
-0如果在内存中表示(其实内存中根本没有-0),原码:1000 0000 0000 0000,补码(最高位溢出舍弃掉)为:0000 0000 0000 0000。发现和正0是一样的二进制存储。
在补码中零的编码只有一个,也就是补码中会比原码多一个编码出来,这个编码就是1000 0000 0000 0000,因为任何一个原码都不可能在转成补码时酿成1000 0000 0000 0000。
所以,人为规定1000 0000 0000 0000这个补码编码为 - 32768。所以,补码中,范围是 - 32768~32767。这句话引自(https://blog.csdn.net/m0_51955470/article/details/120700765)
1000 0000 0000 0000 这样就是表示最小的负数为-2^15。
唉呀,说了这么多终于把存储说完了,那么接下来就说说位运算!
二、位运算
不论正数负数以下都是以补码形式表示的
1.正数位运算
9: 0000 0000 0000 1001
>>1位:0000 0000 0000 0100 最后得到4
>>2位:0000 0000 0000 0010 最后得到2
>>3位:0000 0000 0000 0001 最后得到1
<<1位:0000 0000 0001 0010 最后得到18
<<2位:0000 0000 0010 0100 最后得到36
<<3位:0000 0000 0100 1000 最后得到72
不管左移还是右移都补0就行。发现规律了吗,左移*2,右移/2(数字没移出的情况下)。
2.负数位运算
-9: 1111 1111 1111 0111
>>1位:1111 1111 1111 1011 最后得到-5
>>2位:1111 1111 1111 1101 最后得到-3
>>3位:1111 1111 1111 1110 最后得到-2
<<1位:1111 1111 1110 1110 最后得到-18
<<2位:1111 1111 1101 1100 最后得到-36
<<3位:1111 1111 1011 1000 最后得到-72
左移补0,右移补1。
说在最后:都是自己写的,新人一个,有毛病指出来,共同进步!