唐吉诃德

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  5 Posts :: 75 Stories :: 3 Comments :: 0 Trackbacks

常用链接

留言簿(2)

我参与的团队

搜索

  •  

最新评论

阅读排行榜

评论排行榜

最近笔者一直在做JPEG的解码工作,发现用完全使用哈夫曼树进行解码比较费时,而使用表结构存储编码和值的对应关系比较快捷,但是也存在比较难处理的地方,比如解码工作通常是以位为单位的操作,这里必然会涉及到移位操作,而笔者之前对位的操作很少,经验很欠缺,经过这次历练终于发现了一个自己曾经忽视的东西,那就是C/C++中的移位操作容易出错的情况。

1、什么样的数据类型可以直接移位

char、short、int、long、unsigned char、unsigned short、unsigned int、unsigned long都可以进行移位操作,而double、float、bool、long double则不可以进行移位操作。

2、有符号数据类型的移位操作

对于char、short、int、long这些有符号的数据类型:

  • 对负数进行左移:符号位始终为1,其他位左移
  • 对正数进行左移:所有位左移,即 <<,可能会变成负数
  • 对负数进行右移:取绝对值,然后右移,再取相反数
  • 对正数进行右移:所有位右移,即 >>

3、无符号数据类型的移位操作

对于unsigned char、unsigned short、unsigned int、unsigned long这些无符号数据类型:

没有特殊要说明的,使用<< 和 >> 操作符就OK了

结束语

8086 中存在逻辑移位、算术移位,而C\C++中的移位似乎既不是逻辑移位,也不是算术移位。

比如-1,我们若对它右移1位,C的结果仍旧是-1,事实上无论右移多少位始终是-1,逻辑移位得到的结果(8位表示)应该是-128,所以这点要注意

例子:
1.将 13800138000  转为  91 68 31 08 10 83 00 F0  //91为+ 68国家号 不够位长以F补

unsigned char *tt = new unsigned char[12];
        strcpy((char*)tt,"13800138000");
        tt[11] = 0xFF;
        unsigned char *ss = new unsigned char[6];
        cout << (tt[11]<<4) << endl;
        memset(ss,0xFF,6);
        int k=0;
        for(int i=0; i<12; i=i+2)
        {
                ss[k++] = (tt[i+1]<<4)+(tt[i]&0x0F);
        }
2. 将 整形 转为 3位字节型16进制,如将 整型 888 转为 16进制  00 03 78(Debug下有效,Release下无效)
   char param[4] = {0};
    int iParamLen = 888;
    param[0] = iParamLen >> 16;
    param[1] = ((iParamLen >> 8) << 32) >> 32;
    param[2] = (iParamLen << 32) >> 32;

反之

    char param[4] = {0x00,0x03,0x78};
    int ii1 = 0;
    ii1 = param[0];
    ii1 =ii1 << 8;
    ii1 = ii1 | param[1];
    ii1 =ii1 << 8;
    ii1 = ii1 | param[2];
posted on 2011-01-23 14:53 心羽 阅读(536) 评论(0)  编辑 收藏 引用 所属分类: C/C++

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理