对 unsigned char 先左移 后右移 可以出现两种结果

dongbaoxiong 2014-08-11 11:48:09
关于>> << (左移 右移)今天发现一个搞笑问题

首先,我的编译器是VS2010

我在做个C++ Dll的时候发现:

对一个 unsigned char 先左移 后右移 可以出现两种结果:

1.
int n = 4;
unsigned char tempib = 0Xff;
tempib = ( tempib<<n) >> n; //去掉tempib 的前n 位,n是个变量
2.
int n = 4;
unsigned char tempib = 0Xff;
tempib = tempib<<n; //去掉tempib 的前n 位,n是个变量
tempib = tempib>>n;

我的天呀,1 和2的结果不一样呀。1是:0XFF ,2是:0X0F
破编译器,你左移右移变成4字节操作,好吧,我没意见。能不能不要在一个寄存器里,动都不动,直接移动。
骂归骂,我还是挺喜欢这编译器的,那个编译器没有点不爽的地方
...全文
888 16 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
falloutmx 2014-08-12
  • 打赏
  • 举报
回复
忘记把4改成n了
falloutmx 2014-08-12
  • 打赏
  • 举报
回复
哪有那么复杂
nbit=((nbit<<4)&0xff)>>4;
ri_aje 2014-08-11
  • 打赏
  • 举报
回复
整形提升造成的问题,确实挺隐蔽的。
brookmill 2014-08-11
  • 打赏
  • 举报
回复
我用gcc和g++都得到和楼主一样的结果
dongbaoxiong 2014-08-11
  • 打赏
  • 举报
回复
引用 1 楼 brookmill 的回复:
有点意思。 unsigned char tempib = 0Xff; tempib = ( tempib<<n) >> n; 这个相当于 unsigned char tempib = 0Xff; unsigned int tmp = ((unsigned int)tempib)<<n; // tmp = 0xff0 tmp >>= n; // tmp = 0xff tempib = tmp;
可以这么理解!
brookmill 2014-08-11
  • 打赏
  • 举报
回复 1
有点意思。 unsigned char tempib = 0Xff; tempib = ( tempib<<n) >> n; 这个相当于 unsigned char tempib = 0Xff; unsigned int tmp = ((unsigned int)tempib)<<n; // tmp = 0xff0 tmp >>= n; // tmp = 0xff tempib = tmp;
dongbaoxiong 2014-08-11
  • 打赏
  • 举报
回复
引用 13 楼 brookmill 的回复:
[quote=引用 8 楼 dongbaoxiong 的回复:] 我的n是变量,是会变的,知道n是多少,还有谁会移位?
tempib &= (1 << (sizeof(tempib) * 8 - n)) - 1;[/quote] 简单两个移位就完事了,喷。。。。。为了用个 与 至于吗?你不觉这有点复杂吗?有点专家的感觉呀,不过不像做工程的想法。哈哈!
brookmill 2014-08-11
  • 打赏
  • 举报
回复
引用 8 楼 dongbaoxiong 的回复:
我的n是变量,是会变的,知道n是多少,还有谁会移位?
tempib &= (1 << (sizeof(tempib) * 8 - n)) - 1;
dongbaoxiong 2014-08-11
  • 打赏
  • 举报
回复
引用 11 楼 zhao4zhong1 的回复:
#include <stdio.h>
unsigned char ui;
  signed char si;
char main() {
    ui=(unsigned char)0x80u;
    si=(  signed char)0x80;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);
    ui=ui>>1;
    si=si>>1;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);

    printf("--------------\n");
    ui=(unsigned char)0x80u;
    si=(  signed char)0x80;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);
    ui=((  signed char)ui)>>1;
    si=((unsigned char)si)>>1;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);

    printf("==============\n");

    ui=(unsigned char)0x80u;
    si=(  signed char)0x80;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);
    ui=ui<<1;
    si=si<<1;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);

    printf("--------------\n");
    ui=(unsigned char)0x80u;
    si=(  signed char)0x80;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);
    ui=((  signed char)ui)<<1;
    si=((unsigned char)si)<<1;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);

    return 0;
}
//ui=128
//si=-128
//ui=64
//si=-64
//--------------
//ui=128
//si=-128
//ui=192
//si=64
//==============
//ui=128
//si=-128
//ui=0
//si=0
//--------------
//ui=128
//si=-128
//ui=0
//si=0
好水!哈哈哈哈。。。。。。。。。。。。。
赵4老师 2014-08-11
  • 打赏
  • 举报
回复
#include <stdio.h>
unsigned char ui;
  signed char si;
char main() {
    ui=(unsigned char)0x80u;
    si=(  signed char)0x80;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);
    ui=ui>>1;
    si=si>>1;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);

    printf("--------------\n");
    ui=(unsigned char)0x80u;
    si=(  signed char)0x80;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);
    ui=((  signed char)ui)>>1;
    si=((unsigned char)si)>>1;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);

    printf("==============\n");

    ui=(unsigned char)0x80u;
    si=(  signed char)0x80;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);
    ui=ui<<1;
    si=si<<1;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);

    printf("--------------\n");
    ui=(unsigned char)0x80u;
    si=(  signed char)0x80;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);
    ui=((  signed char)ui)<<1;
    si=((unsigned char)si)<<1;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);

    return 0;
}
//ui=128
//si=-128
//ui=64
//si=-64
//--------------
//ui=128
//si=-128
//ui=192
//si=64
//==============
//ui=128
//si=-128
//ui=0
//si=0
//--------------
//ui=128
//si=-128
//ui=0
//si=0
dongbaoxiong 2014-08-11
  • 打赏
  • 举报
回复
引用 9 楼 dongbaoxiong 的回复:
[quote=引用 5 楼 falloutmx 的回复:] 确实是这样。不过一般我都是直接写 tempib = tempib & 0x0f
我一想,用bitset 可以用与,不过那也不见得比移位好多少?[/quote] 还可以定义个数组a[8] = {0X00,0X01,0x03,0x07,0x0F,0x1F,0x3F,0x7F};直接与,这个不错,用空间换时间。
dongbaoxiong 2014-08-11
  • 打赏
  • 举报
回复
引用 5 楼 falloutmx 的回复:
确实是这样。不过一般我都是直接写 tempib = tempib & 0x0f
我一想,用bitset 可以用与,不过那也不见得比移位好多少?
dongbaoxiong 2014-08-11
  • 打赏
  • 举报
回复
引用 5 楼 falloutmx 的回复:
确实是这样。不过一般我都是直接写 tempib = tempib & 0x0f
我的n是变量,是会变的,知道n是多少,还有谁会移位?
wanlong1215 2014-08-11
  • 打赏
  • 举报
回复
看的好迷糊啊
风行踩火轮 2014-08-11
  • 打赏
  • 举报
回复
这个确实有些隐蔽
falloutmx 2014-08-11
  • 打赏
  • 举报
回复
确实是这样。不过一般我都是直接写 tempib = tempib & 0x0f

65,183

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧