c语言 右移12位是什么意思,C语言左移和右移

事情的发生:

某日工作中有个需求是将不同的数值存到char的前4位和后4位中。

恰好同事中有同样取得32位int的前8位当成一个数值的代码:

//取得32位中的高八位组成的值

#define U32_HIGH_8(val) ((val >> 24) & 0X000000FF)

好奇心就来了,在右移24位以后是否还有必要再与上(&)0x000000FF将高位的数据彻底清零呢?

讨论:

考虑以下几个问题:

(1)

char i = 0x40; //二进制中i的表示为:0100 0000

unsighedchar j = 0x40;

i<<= 1;

j<<= 1;//问:i和j分别等于多少?

i 左移以后的二进制表示为:1000 0000,由定义的有符号char解释为:i = -128

j 左移以后的二进制表示为:1000 0000,由定义的无符号(unsigned char)解释为:i = 128

(2)

char i = 0x80;//二进制中表示为:1000 0000

char j = 0x40;//二进制中i的表示为:0100 0000

j >>= 1;

i>>= 1;//问i和j等于多少?

i 右移以后的二进制表示为:1100 0000(右移对于负数来说符号位右移,高位补1),故i=-64

j 右移以后的二进制表示为:0010 0000(右移对于正数来说符号位右移,高位补0),故i=32

(3)

char i = -3;//二进制表示为:1111 1101//i << 1是多少? i >> 1是多少?

i << 1的二进制表示为:1111 1010(左移为逻辑左移高位丢弃,低位补0),由有符号数char解释为:-6

i >> 1的二进制表示为:1111 1110(右移为算术右移,对于负数来说高位补1),有有符号数char解释为:2

左移右移总结:

右移左移涉及丢弃、补0或补1,但是最终对这一串二进制解释成什么数值是通过变量的定义(是否unsigned)来决定的。

左移始终是逻辑左移,即丢弃高位,低位补0;

右移是算术右移,对于有符号数:正数右移高位补0,负数右移高位补1。对于无符号数:逻辑右移(即高位补0,低位丢弃);

结论:

那么开头的问题是:是否还有必要再与上(&)0x000000FF将高位的数据彻底清零呢?

我认为还是有必要的,因为并不知道值的类型是否是无符号数(unsigned),假如原本的32位数是普通的int类型且二进制为(1000 0000……0000 0000),那么取高8位的时候的二进制表示(1111 1111……1000 0000),那么这个数解释出来就会非常大且出错。如果是无符号数的话还算正常。

因此为了避免日后定义错类型导致的错误,还是将移位以后的二进制的高位与上(&)0,将高位彻底清0为好。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言中的运算符包括左移运算符(<<)、右移运算符(>>)、按与运算符(&)、按或运算符(|)和按异或运算符(^)。其中左移运算符和右移运算符可以用来对一个进行移操作。无符号左移右移是指将一个无符号的二进制表示向左或向右移动指定的,移动后的空用0填充。下面是一个无符号左移的例子: 引用:例子二:无符号左移 #include <stdio.h> int main(){ unsigned int a = 0x80000001; int i=0; for(;i<64;i++){ printf("left %d:%08x,%u\n",i,a<<i,a<<i); } } 在这个例子中,我们定义了一个无符号整型变量a,并将其初始化为0x80000001。然后我们使用for循环对a进行了64次左移操作,每次左移从0到63。在每次左移后,我们使用printf函输出了左移左移后的结果以及结果的十进制表示。可以看到,每次左移后,a的值都会乘以2的移动次方。 无符号右移是指将一个无符号的二进制表示向右移动指定的,移动后的空用0填充。下面是一个无符号右移的例子: 引用:例子四:无符号右移 #include <stdio.h> int main(){ unsigned int a = 0x10000001; int i=0; for(;i<64;i++){ printf("left %d:%08x,%u\n",i,a>>i,a>>i); } } 在这个例子中,我们定义了一个无符号整型变量a,并将其初始化为0x10000001。然后我们使用for循环对a进行了64次右移操作,每次右移从0到63。在每次右移后,我们使用printf函输出了右移右移后的结果以及结果的十进制表示。可以看到,每次右移后,a的值都会除以2的移动次方。 需要注意的是,对于有符号左移右移,如果移动后的空用符号填充,那么就会出现符号溢出的问题。例如,如果将一个有符号整型变量i的值左移3,那么移动后的空将用符号填充。如果i的值为8,那么左移3后,i的值将变为64,而不是24。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值