C语言中无符号数和有符号数的左移和右移

本文探讨了在单片机开发中,无符号数和有符号数进行左移和右移操作时的行为。无符号数左移丢弃高位并补0,右移丢弃低位并补0;有符号数左移保持符号,右移符号位为1时高位补1。实验基于AT32F403AVCT7单片机和MDK-ARMPlus V5.25.2.0编译器进行验证。
摘要由CSDN通过智能技术生成

在单片机开发中,通常会使用左移和右移操作做快速的乘法和除法运算。

例如,将0x0001左移1位,相当于乘以2^1左移2位相当于乘以2^2,以此类推,左移n位,相当于乘以2^n。右移则相当于除以2^n。

那么对于无符号数和有符号数,对于左移和右移的操作分别是如何呢?下面通过实验来进行验证:

对于无符号数的左移和右移,代码片段如下:

void main(void){
    static UINT16 sTemp;
    
    sTemp = 0x0001;
    sTemp = sTemp <<1 ;

    sTemp = 0x0400;
    sTemp = sTemp >> 1;
    
    sTemp = 0xFFFF;
    sTemp = sTemp >> 1;

    while(1);
}

 仿真运行结果:

    sTemp = 0x0001;
    sTemp = sTemp <<1 ;

执行左移后,sTemp值为0x0002

0000000000000001B --> 0000000000000010B

可见:无符号数左移策略是丢弃最高位,低位补0

    sTemp = 0x0400;
    sTemp = sTemp >> 1;

执行右移后,sTemp的值为0x0200

0000010000000000B --> 0000001000000000B

可见:无符号数执行右移策略是丢弃最低位,高位补0

    sTemp = 0xFFFF;
    sTemp = sTemp >> 1;

执行右移后,sTemp的值为0x7FFF

1111111111111111B --> 0111111111111111B

右移策略与前面相同。

对于有符号数,测试代码如下:

void main(void){
    static INT16 sTemp;

    sTemp = 0x0001;
    sTemp = sTemp << 1;

    sTemp = 0x4000;
    sTemp = sTemp << 1;
    
    sTemp = 0x8000;
    sTemp = sTemp >> 1;
    
    sTemp = 0x8000;
    sTemp = sTemp << 1;
    

    while(1);
}

仿真进行测试:

    sTemp = 0x0001;
    sTemp = sTemp <<1 ;

执行左移后,sTemp值为0x0002

0000000000000001B ---> 0000000000000010B

可见

有符号数左移,符号位为0,执行左移,舍弃高位,低位补0

    sTemp = 0x4000;
    sTemp = sTemp << 1;

 执行左移后,sTemp值为0x8000

0100000000000000 --> 1000000000000000B

可见策略与前面一致,但需注意,十进制数由16384变为-32768.这和定义的数据类型有关

 

    sTemp = 0x8000;
    sTemp = sTemp >> 1;

有符号数,符号位为1,执行右移操作

sTemp值变为0xC000

1000000000000000B --> 1100000000000000B

可见有符号数右移,符号位为1时,执行右移,舍弃低位,高位补1.

    sTemp = 0x8000;
    sTemp = sTemp << 1;

有符号数,符号位为1,执行左移操作

sTemp变为0x0000

可见有符号数左移,符号位为1时,执行左移,舍弃高位,低位补0

总结

无符号数有符号数
左移右移左移右移
最高位为0舍弃高位,低位补0舍弃低位,高位补0舍弃高位,低位补0舍弃低位,高位补0
最高位为1舍弃低位,高位补1

以上结论使用单片机为AT32F403AVCT7,IDE和编译器信息如下:


IDE-Version:
μVision V5.25.2.0

Tool Version Numbers:
Toolchain:        MDK-ARM Plus  Version: 5.25.2.0
Toolchain Path:    D:\Keil_v5\ARM\ARMCC\Bin
C Compiler:         Armcc.exe        V5.06 update 6 (build 750)
Assembler:          Armasm.exe        V5.06 update 6 (build 750)
Linker/Locator:     ArmLink.exe        V5.06 update 6 (build 750)
Library Manager:    ArmAr.exe        V5.06 update 6 (build 750)
Hex Converter:      FromElf.exe        V5.06 update 6 (build 750)
CPU DLL:               SARMCM3.DLL          V5.25.2.0
Dialog DLL:         DCM.DLL              V1.17.1.0
Target DLL:             CMSIS_AGDI.dll       V1.29.10.0
Dialog DLL:         TCM.DLL              V1.35.1.0

 其他编译器是否满足此规律,需要另行验证。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值