移位运算的问题

正数

正数的原码,反码,补码相同
正数,左移乘2,右移除2
左移右移都补0
如果左移丢1,会出错;如果右移丢1,会影响精度

负数

负数的原码左移补0,右移也补0
    左移丢1,会出错;右移丢1,会出错
负数的反码左移补1,右移补1(因为原码补0不影响,那么反码应该补1)
    左移丢0,会出错(这里的0是原码中的1),右移丢0,会出错
负数的补码从右往左的第一个1(包括这个1)往右的数和原码一样,是原码
    往左和补码一样,是补码
        所以补码可以看成由反码和原码两部分组成
            那么左移补0,右移补1
    左移丢1(丢的是原码的1),会出错;右移丢0(丢的是反码的0),会出错

举例

-26
二进制表示:-001 1010
原码:1001 1010
反码:1110 0101
补码:1110 0110

可见红框中补码与原码相同,蓝绿框中补码与反码相同

由于只有7位数值位,一位符号位,那么所表示的数值的大小是有限的,所以不能一直左移,那么左移到什么程度就该停止防止溢出呢?

    右移会影响精度,会出现补码和原码反码右移相同的位数,最终的结果却不一样的情况,不再画图表示
上面的图片体现了计算机判断左移右移是否正确的方法,即对于原码左移丢1会出错,对于反码左移丢0会出错,也就是说原码的1不能丢,反码的0不能丢,那么对于补码呢?
    补码由两部分组成
    补码的反码部分:0不能丢,丢了会出错
    补码的原码部分:1不能丢,丢了会出错

但是有一个特例
-32

-32的补码左移两位,那么-32原码部分的那个1就会被移掉,但是并不错,因为左移后的1000 0000对于补码是-128,-32左移两次相当于乘以4等于-128,但是左移丢原码的1应该不对啊,但是结果却是对的,那么计算机如何处理这个特例呢?

    这其中的特殊之处,就是因为补码中少表示一个-0,就可以多表示一个数,这个多表示的数就是-128,对于原码和反码,如果有一位符号位的话,是表示不了-128的,但是对于补码却可以。
如果计算机是通过判断左移丢的1是原码的1,左移丢的0是反码的0来判断是否溢出的话,那么-32左移丢原码的1就是错的,但结果却是对的,计算机是认为他是对的输出呢,还是认为他是错的不输出呢?
    如果认为是对的,那么就不能按丢的1或0是不是原码或反码的规则来判断是否左移运算是否正确?
        那么不是这种判断方法,那又是什么方法呢?
            要么有一套规则处理这个特例,要么就得有一个更好的规则可以包括这个特例。
    如果认为是错的,那补码即使可以多表示出一个-128,但是在实际计算中却不能表示出来(认为移位运算得出的-128是错的,不应该存在),多表示这个-128有什么意义呢?
### 单片机中移位运算的实现方法与示例代 在单片机编程中,移位运算是非常重要的位操作技术,广泛应用于数值优化、数据类型转换及寄存器位操作等领域。以下是移位运算的基本原理及其在单片机中的实现方式。 #### 1. 移位运算的基本概念 移位运算包括左移(`<<`)和右移(`>>`)。左移将二进制数向高位移动指定的位数,同时低位补零;右移则将二进制数向低位移动指定的位数,对于无符号数高位补零,而对于有符号数高位补符号位[^2]。 #### 2. 移位运算的应用场景 移位运算常用于以下场景: - **乘除法替代**:左移一位相当于乘以2,右移一位相当于除以2。 - **位操作**:通过移位操作可以直接控制硬件接口的状态。 - **数据压缩与解压缩**:利用移位操作可以高效地处理位级数据[^3]。 #### 3. 示例代:左移与右移运算 以下是一个简单的C语言示例,展示了如何在单片机中使用移位运算: ```c #include <reg51.h> // 定义一个宏,用于控制某个特定的位 #define CONTROL_BIT (0x01 << 5) // 将1左移5位,控制第6位 void main() { unsigned char data = 0x00; // 左移操作:将data的值乘以4 data = data << 2; // 等效于 data * 4 P1 = data; // 输出到P1端口 // 右移操作:将data的值除以2 data = data >> 1; // 等效于 data / 2 P1 = data; // 输出到P1端口 // 使用宏控制特定位 P1 |= CONTROL_BIT; // 设置第6位为1 P1 &= ~CONTROL_BIT; // 清除第6位为0 while (1); // 保持程序运行 } ``` #### 4. 注意事项 - 在实际应用中,应避免直接使用魔法数字(如`0x20`),建议通过宏定义或枚举来提高代可读性[^3]。 - 对于有符号数的右移操作,需注意符号扩展问题,确保结果符合预期[^2]。 #### 5. 性能优势 研究表明,移位运算在速度和代可读性方面具有显著优势,是单片机开发中不可或缺的编程工具[^2]。通过合理运用移位操作符,可以显著提高程序的效率和灵活性[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值