CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C语言

位操作技巧--走过路过,机会不要错过

楼主QunKangLi(心里面疼得有点发酸 一定是有雾来了 打湿了我的眼眶)2005-04-30 10:44:21 在 C/C++ / C语言 提问

发黄的心事请交付流水,向远去的雾霭行个注目礼,祝大家五一好心情...  
   
  今日得闻偶裤衩多一条,狂喜,散分ing...  
   
  前段时间好多人问位操作相关的技术,特附以前收集的位操作技巧N个,希望新人捧场,高手斧正,大虾补充  
   
  /******************************************************************/  
  检测一个无符号数是不为2^n-1(^为幂):   x&(x+1)  
   
  将最右侧0位改为1位:   x   |   (x+1)  
   
  二进制补码运算公式:  
  -x   =   ~x   +   1   =   ~(x-1)  
  ~x   =   -x-1    
  -(~x)   =   x+1  
  ~(-x)   =   x-1  
  x+y   =   x   -   ~y   -   1   =   (x|y)+(x&y)    
  x-y   =   x   +   ~y   +   1   =   (x|~y)-(~x&y)    
  x^y   =   (x|y)-(x&y)  
  x|y   =   (x&~y)+y  
  x&y   =   (~x|y)-~x  
   
  x==y:         ~(x-y|y-x)  
  x!=y:         x-y|y-x  
  x<   y:         (x-y)^((x^y)&((x-y)^x))  
  x<=y:         (x|~y)&((x^y)|~(y-x))  
  x<   y:         (~x&y)|((~x|y)&(x-y))//无符号x,y比较  
  x<=y:         (~x|y)&((x^y)|~(y-x))//无符号x,y比较  
   
   
  使用位运算的无分支代码:  
   
  计算绝对值  
  int   abs(   int   x   )    
  {  
  int   y   ;  
  y   =   x   >>   31   ;  
  return   (x^y)-y   ;//or:   (x+y)^y  
  }  
   
  符号函数:sign(x)   =   -1,   x<0;   0,   x   ==   0   ;   1,   x   >   0  
  int   sign(int   x)  
  {  
  return   (x>>31)   |   (unsigned(-x))>>31   ;//x=-2^31时失败(^为幂)  
  }  
   
  三值比较:cmp(x,y)   =   -1,   x<y;   0,   x==y;   1,   x   >   y  
  int   cmp(   int   x,   int   y   )  
  {  
  return   (x>y)-(x-y)   ;  
  }  
   
  doz=x-y,   x>=y;   0,   x<y  
  int   doz(int   x,   int   y   )  
  {  
  int   d   ;  
  d   =   x-y   ;  
  return   d   &   ((~(d^((x^y)&(d^x))))>>31)   ;  
  }  
   
  int   max(int   x,   int   y   )    
  {  
  int   m   ;  
  m   =   (x-y)>>31   ;    
  return   y   &   m   |   x   &   ~m   ;  
  }  
   
  不使用第三方交换x,y:  
  1.x   ^=   y   ;   y   ^=   x   ;   x   ^=   y   ;  
  2.x   =   x+y   ;   y   =   x-y   ;   x   =   x-y   ;  
  3.x   =   x-y   ;   y   =   y+x   ;   x   =   y-x   ;  
  4.x   =   y-x   ;   x   =   y-x   ;   x   =   x+y   ;    
   
  双值交换:x   =   a,   x==b;   b,   x==a//常规编码为x   =   x==a   ?   b   :a   ;  
  1.x   =   a+b-x   ;  
  2.x   =   a^b^x   ;  
   
  下舍入到2的k次方的倍数:  
  1.x   &   ((-1)<<k)  
  2.(((unsigned)x)>>k)<<k  
  上舍入:  
  1.   t   =   (1<<k)-1   ;   x   =   (x+t)&~t   ;  
  2.t   =   (-1)<<k   ;   x   =   (x-t-1)&t   ;  
   
  位计数,统计1位的数量:  
  1.  
  int   pop(unsigned   x)  
  {  
  x   =   x-((x>>1)&0x55555555)   ;  
  x   =   (x&0x33333333)   +   ((x>>2)   &   0x33333333   )   ;  
  x   =   (x+(x>>4))   &   0x0f0f0f0f   ;  
  x   =   x   +   (x>>8)   ;  
  x   =   x   +   (x>>16)   ;  
  return   x   &   0x0000003f   ;  
  }  
  2.  
  int   pop(unsigned   x)   {  
  static   char   table[256]   =   {   0,1,1,2,   1,2,2,3,   ....,   6,7,7,8   }   ;  
  return   table[x&0xff]+table[(x>>8)&0xff]+table[(x>>16)&0xff]+table[(x>>24)]   ;  
  }  
   
  奇偶性计算:  
  x   =   x   ^   (   x>>1   )   ;  
  x   =   x   ^   (   x>>2   )   ;  
  x   =   x   ^   (   x>>4   )   ;  
  x   =   x   ^   (   x>>8   )   ;  
  x   =   x   ^   (   x>>16   )   ;  
  结果中位于x最低位,对无符号x,结果的第i位是原数第i位到最左侧位的奇偶性  
   
   
  位反转:  
  unsigned   rev(unsigned   x)  
  {  
  x   =   (x   &   0x55555555)   <<   1   |   (x>>1)   &   0x55555555   ;  
  x   =   (x   &   0x33333333)   <<   2   |   (x>>2)   &   0x33333333   ;  
  x   =   (x   &   0x0f0f0f0f)   <<   4   |   (x>>4)   &   0x0f0f0f0f   ;  
  x   =   (x<<24)   |   ((x&0xff00)<<8)   |   ((x>>8)   &   0xff00)   |   (x>>24)   ;  
  return   x   ;  
  }  
   
  递增位反转后的数:  
  unsigned   inc_r(unsigned   x)  
  {  
  unsigned   m   =   0x80000000   ;  
  x   ^=   m   ;  
  if(   (int)x   >=   0   )    
  do   {   m   >>=   1   ;   x   ^=   m   ;   }   while(   x   <   m   )   ;  
  return   x   ;  
  }  
   
  混选位:  
  abcd   efgh   ijkl   mnop   ABCD   EFGH   IJKL   MNOP->aAbB   cCdD   eEfF   gGhH   iIjJ   kKlL   mMnN   oOpP  
  unsigned   ps(unsigned   x)  
  {  
  unsigned   t   ;  
  t   =   (x   ^   (x>>8))   &   0x0000ff00;   x   =   x   ^   t   ^   (t<<8)   ;  
  t   =   (x   ^   (x>>4))   &   0x00f000f0;   x   =   x   ^   t   ^   (t<<4)   ;  
  t   =   (x   ^   (x>>2))   &   0x0c0c0c0c;   x   =   x   ^   t   ^   (t<<2)   ;  
  t   =   (x   ^   (x>>1))   &   0x22222222;   x   =   x   ^   t   ^   (t<<1)   ;  
  return   x   ;  
  }  
   
  位压缩:  
  选择并右移字x中对应于掩码m的1位的位,如:compress(abcdefgh,01010101)=0000bdfh  
  compress_left(x,m)操作与此类似,但结果位在左边:   bdfh0000.  
  unsigned   compress(unsigned   x,   unsigned   m)  
  {  
  unsigned   mk,   mp,   mv,   t   ;  
  int   i   ;  
   
  x   &=   m   ;  
  mk   =   ~m   <<   1   ;  
  for(   i   =   0   ;   i   <   5   ;   ++i   )   {  
  mp   =   mk   ^   (   mk   <<   1)   ;  
  mp   ^=   (   mp   <<   2   )   ;  
  mp   ^=   (   mp   <<   4   )   ;  
  mp   ^=   (   mp   <<   8   )   ;  
  mp   ^=   (   mp   <<   16   )   ;  
  mv   =   mp   &   m   ;  
  m   =   m   ^   mv   |   (mv   >>   (1<<i)   )   ;  
  t   =   x   &   mv   ;  
  x     =   x   ^   t   |   (   t   >>   (   1<<i)   )   ;  
  mk   =   mk   &   ~mp   ;  
  }  
  return   x   ;  
  }  
   
   
  位置换:  
  用32个5位数表示从最低位开始的位的目标位置,结果是一个32*5的位矩阵,  
  将该矩阵沿次对角线转置后用5个32位字p[5]存放。  
  SAG(x,m)   =   compress_left(x,m)   |   compress(x,~m)   ;  
  准备工作:  
  void   init(   unsigned   *p   )   {  
  p[1]   =   SAG(   p[1],   p[0]   )   ;  
  p[2]   =   SAG(   SAG(   p[2],   p[0]),   p[1]   )   ;  
  p[3]   =   SAG(   SAG(   SAG(   p[3],   p[0]   ),   p[1]),   p[2]   )   ;  
  p[4]   =   SAG(   SAG(   SAG(   SAG(   p[4],   p[0]   ),   p[1])   ,p[2]),   p[3]   )   ;  
  }  
  实际置换:  
  int   rep(   unsigned   x   )   {  
  x   =   SAG(x,p[0]);  
  x   =   SAG(x,p[1]);  
  x   =   SAG(x,p[2]);  
  x   =   SAG(x,p[3]);  
  x   =   SAG(x,p[4]);  
  return   x   ;  
  }  
   
  二进制码到GRAY码的转换:  
  unsigned   B2G(unsigned   B   )  
  {  
  return   B   ^   (B>>1)   ;  
  }  
  GRAY码到二进制码:  
  unsigned   G2B(unsigned   G)  
  {  
  unsigned   B   ;  
  B   =   G   ^   (G>>1)   ;  
  B   =   G   ^   (G>>2)   ;  
  B   =   G   ^   (G>>4)   ;  
  B   =   G   ^   (G>>8)   ;  
  B   =   G   ^   (G>>16)   ;  
  return   B   ;  
  }  
   
  找出最左0字节的位置:  
  int   zbytel(   unsigned   x   )  
  {  
  static   cahr   table[16]   =   {   4,3,2,2,   1,1,1,1,   0,0,0,0,   0,0,0,0   }   ;  
  unsigned   y   ;  
  y   =   (x&0x7f7f7f7f)   +   0x7f7f7f7f   ;  
  y   =   ~(y|x|0x7f7f7f7f)   ;  
  return   table[y*0x00204081   >>   28]   ;//乘法可用移位和加完成  
  }  
   
  /******************************************************************/  
  问题点数:200、回复次数:117Top

1 楼useresu(俗人)(灌水是我无言的抗议)回复于 2005-04-30 10:47:26 得分 2

好贴啊,  
  帮顶Top

2 楼kiko_lee(清醒的迷茫中)回复于 2005-04-30 10:49:26 得分 2

已经收藏了,确实不错。谢谢拉Top

3 楼qrlvls( 空 气 )回复于 2005-04-30 10:49:31 得分 2

支持支持Top

4 楼qrlvls( 空 气 )回复于 2005-04-30 10:51:15 得分 2

支持支持Top

5 楼laiyiling(陌生人[MVP])回复于 2005-04-30 10:52:09 得分 2

收藏Top

6 楼yjm0105(流云)回复于 2005-04-30 10:52:48 得分 2

UPTop

7 楼chunhai12(小海)回复于 2005-04-30 10:54:02 得分 2

占个位子先Top

8 楼Roaming_Sheep(Roaming Sheep)回复于 2005-04-30 10:55:01 得分 2

mark  
  Top

9 楼junguo(junguo)回复于 2005-04-30 10:55:12 得分 2

upTop

10 楼yunlang2233187(冰水湖)回复于 2005-04-30 10:57:06 得分 2

upTop

11 楼lightning8(lightning)回复于 2005-04-30 10:58:08 得分 2

太好了,收藏中........................Top

12 楼akindo(Akindo)回复于 2005-04-30 10:59:43 得分 2

THANKSTop

13 楼heskyII(赫斯基)回复于 2005-04-30 11:00:00 得分 2

不错,雷锋贴.  
  抢分Top

14 楼vcleaner(我没当大哥很久了.......)回复于 2005-04-30 11:12:00 得分 2

收藏,UP,接分!Top

15 楼kugou123(酷狗)(彪悍的人生,不需要解释 www.xiaozhou.net)回复于 2005-04-30 11:12:59 得分 2

UPTop

16 楼wwxsoft(婉儿)回复于 2005-04-30 11:13:11 得分 2

upTop

17 楼NewWriter(新手)回复于 2005-04-30 11:15:08 得分 2

upTop

18 楼MTring(不想成为别人的羔羊,请你成为一头狼吧!)回复于 2005-04-30 11:18:09 得分 2

不知道位操作主要用在什么地方?Top

19 楼mbcw(mbcw)回复于 2005-04-30 11:23:14 得分 2

推荐一本书《高效程序的奥秘》,英文名字“Hacker's   Delight”,楼主  
  收藏的大部分内容,在书中都有描述(甚至附带证明)。  
  Top

20 楼galanz(微小就是永恒)回复于 2005-04-30 11:23:38 得分 2

markTop

21 楼kobefly(科比--网络学习中)回复于 2005-04-30 11:23:45 得分 2

谢谢Top

22 楼Enirax(旁观者)回复于 2005-04-30 11:32:48 得分 2

好贴,很有用  
  感谢搂主中.....Top

23 楼homtipo()回复于 2005-04-30 11:34:38 得分 2

支持。mark。Top

24 楼Audi_TT(人不嚣张枉少年)回复于 2005-04-30 11:38:10 得分 2

帮顶Top

25 楼pomelowu(羽战士)回复于 2005-04-30 11:38:21 得分 2

散分都散得如此有技术含量,pfpfTop

26 楼flying_dancing(小混混-_-)回复于 2005-04-30 11:44:05 得分 2

好LONG                     -_-  
  漫漫     品尝Top

27 楼QunKangLi(心里面疼得有点发酸 一定是有雾来了 打湿了我的眼眶)回复于 2005-04-30 11:45:04 得分 0

采用C语言编程的时候,函数中形式参数的数目通常是确定的,在调用时要依次给出与形式参数对应的所有实际参数。但在某些情况下希望函数的参数个数可以根据需要确定。典型的例子有大家熟悉的函数printf()、scanf()和系统调用execl()等。那么它们是怎样实现的呢?    
   
    C编译器通常提供了一系列处理这种情况的宏,以屏蔽不同的硬件平台造成的差异,增加程序的可移植性。这些宏包括va—start、va—arg和va—end等。    
   
    使用这些宏有两种不同的形式,二者在程序中包括的头文件不同,宏的定义也存在一些差别。这两种方式对应的头文件和宏的声明见表1。    
   
    采用ANSI标准形式时,参数个数可变的函数的原型声明是:    
   
    type   funcname(type   para1,   type   para2,   ...)    
   
    这种形式至少需要一个普通的形式参数,后面的省略号不表示省略,而是函数原型的一部分,type是函数返回值和形式参数的类型。    
   
    采用与UNIX   System   V兼容的声明方式时,参数个数可变的函数原型是:    
   
    type   funcname(va—alist)    
   
    va—dcl    
   
    这种形式不需要提供任何普通的形式参数,type是函数返回值的类型。va—dcl是对函数原型声明中参数va—alist的详细声明,实际是一个宏定义,对不同的硬件平台采用不同的类型来定义,但在最后都包括了一个分号,因此va—dcl后不再需要加上分号了。va—dcl在代码中必须原样给出,va—alist在VC中可以原样给出,也可以略去,但在UNIX上的CC或Linux上的GCC中都要省略掉。此外,采用头文件stdarg.h编写的程序是符合ANSI标准的,可以在各种操作系统和硬件上运行,而采用头文件varargs.h的方式仅仅是为了与以前的程序兼容。所以建议大家使用前者。两种方式的基本原理是一致的,只是在语法形式上有一些细微的区别。以下主要就前一种方式对参数的处理做出说明。    
   
    va—start使argp指向第一个可选参数。va—arg返回参数列表中的当前参数并使argp指向参数列表中的下一个参数。va—end把argp指针清为NULL。函数体内可以多次遍历这些参数,但是都必须以va—start开始,并以va—end结尾。    
   
    调用者在实际调用参数个数可变的函数时,要通过一定的方法指明实际参数的个数,例如把最后一个参数置为空字符串(系统调用execl()就是这样的)、-1或其他的方式。    
   
    下面给出一个具体的例子,前一部分是采用了符合ANSI标准形式的代码,后一部分是采用了与UNIX   System   V兼容方式的代码。代码中加了一些注释,这里就不再解释了。该例子已经在VC/Windows   NT4.0、CC/AIX4.3.2.0、GCC/Redhat   Linux   6.0环境下编译并正常运行。    
   
    1.演示如何使用参数个数可变的函数,采用ANSI标准形式    
   
    #include   〈stdio.h〉    
   
    #include   〈string.h〉    
   
    #include   〈stdarg.h〉    
   
    /   函数原型声明,至少需要一个确定的参数,注意括号内的省略号   /    
   
    int   demo(   char   ,   ...   );    
   
    void   main(   void   )    
   
    {    
   
       demo(″DEMO″,   ″This″,   ″is″,   ″a″,   ″demo!″,   ″\0″);    
   
    }    
   
    /   ANSI标准形式的声明方式,括号内的省略号表示可选参数   /    
   
    int   demo(   char   msg,   ...   )    
   
    {    
   
    va—list   argp;    
   
    /   定义保存函数参数的结构   /    
   
    int   argno   =   0;   /   纪录参数个数   /    
   
    char   para;    
   
    /   存放取出的字符串参数   /    
   
    /   argp指向传入的第一个可选参数,msg是最后一个确定的参数   /    
   
    va—start(   argp,   msg   );    
   
    while   (1)   {    
   
    para   =   va—arg(   argp,   char   );    
   
    /   取出当前的参数,类型为char   .   /    
   
       if   (   strcmp(   para,   ″\0″)   ==   0   )    
   
    /   采用空串指示参数输入结束   /    
   
    break;    
   
    printf(″Parameter   #%d   is:   %s\n″,   argno,   para);    
   
       argno++;    
   
    }    
   
       va_end(   argp   );    
   
       /   将argp置为NULL   /    
   
      return   0;    
   
    }    
   
    2.演示如何使用参数个数可变的函数,采用与UNIX   System   V兼容的方式    
   
    #include   〈stdio.h〉    
   
    #include   〈string.h〉    
   
    #include   〈varargs.h〉    
   
    /   函数原型声明,括号内的类型va—list在VC/Windows   NT4.0可以保留,但在AIX和Linux下需要去掉,即改成int   demo(   )   /    
   
    int   demo(   va—list   );    
   
    void   main(   void   )    
   
    {    
   
       demo(″This″,   ″is″,   ″a″,   ″demo!″,   ″\0″);    
   
    }    
   
    /   UNIX   System   V采用的声明方式,括号内是va—alist,不是va—list,而且va—dcl后面不需要分号   /    
   
    int   demo(   va—alist   )    
   
    va—dcl      
   
    {    
   
    va—list   argp;    
   
       /   定义保存函数参数的结构   /    
   
         int   argno   =   0;   /   纪录参数个数   /    
   
         char   para;    
   
    /   存放取出的字符串参数   /    
   
    va—start(   argp   );    
   
    /   argp指向第一个可选参数   /    
   
    while   (1)   {    
   
    para   =   va—arg(   argp,   char   );    
   
    /   取出当前的参数,类型为char   /    
   
         if   (   strcmp(   para,   ″\0″)   ==   0   )    
   
    /   采用空串指示参数输入结束   /    
   
         break;    
   
         printf(″Parameter   #%d   is:   %s\n″,   argno,   para);    
   
         argno++;    
   
         }    
   
    va_end(   argp   );   /   将argp置为NULL   /    
   
    return   0;    
   
    }    
   
      表1       ANSI标准形式   UNIX   SystemⅤ兼容方式    
  头文件   #include   〈stdarg.h〉   #include   〈varargs.h〉    
  va_start   void   va_start(argp,   paran)   va_list   argp;     void   va_start(argp)   va_list   argp;    
  va_arg   type   va_arg(argp,   type)   va_list   argp;   type   va_arg(argp,   type)   va_list   argp;    
  va_end   void   va_end(argp)   va_list   argp;   void   va_end(argp)   va_list   argp;    
     
     
     
     
     
  Top

28 楼zhang_jiang(Solar)回复于 2005-04-30 11:55:20 得分 2

收录之!Top

29 楼wodeyouxian(人生如梦)回复于 2005-04-30 11:57:11 得分 2

学习Top

30 楼DigNet(ww-zetor)回复于 2005-04-30 11:58:44 得分 2

谢谢!Top

31 楼lanphaday(恋花蝶)回复于 2005-04-30 12:17:26 得分 2

good,,3xTop

32 楼avalonBBS("︶.︶メ)→( ̄ε ̄メ)回复于 2005-04-30 12:18:51 得分 2

 
   
  markTop

33 楼viyar(云烟不倒)回复于 2005-04-30 12:21:16 得分 2

好好研究!Top

34 楼fhvk(Green tea)回复于 2005-04-30 12:22:07 得分 2

markTop

35 楼zhousqy(标准C匪徒)(甩拉,甩拉)回复于 2005-04-30 12:26:34 得分 2

李兄、好贴啊。顶!Top

36 楼dongfa(一桶江湖( http://www.codelive.net ))回复于 2005-04-30 12:30:58 得分 2

接分呀~~~~Top

37 楼oo(为了名副其实,努力学习oo技术ing)回复于 2005-04-30 12:31:59 得分 2

markTop

38 楼rwdx(忆)回复于 2005-04-30 12:43:20 得分 2

收藏!Top

39 楼mefit(何足道)回复于 2005-04-30 12:55:56 得分 2

upTop

40 楼ltc_mouse(野地芳菲)回复于 2005-04-30 13:02:52 得分 2

好帖,收藏!Top

41 楼liujingfu123(Oh_My_GoD)回复于 2005-04-30 13:20:10 得分 2

好东西!  
  Top

42 楼y39242(叶叶依风)回复于 2005-04-30 13:24:14 得分 2

回复有好处吗???怎么大家都这么简短的说"好"?  
                                                                            ---新来大虾Top

43 楼zixiu2008(子休)回复于 2005-04-30 13:33:58 得分 2

markTop

44 楼abcabc999()回复于 2005-04-30 13:35:29 得分 2

太好了Top

45 楼tfq(大梦谁先觉)回复于 2005-04-30 18:34:56 得分 2

真不错,收藏!  
  高手多多做慈善事业噢Top

46 楼niuman(青橄榄)回复于 2005-04-30 18:36:59 得分 2

markTop

47 楼lzwei3842(赐缘)回复于 2005-04-30 18:49:18 得分 2

好啊,,,  
  UPTop

48 楼jk88811(你的就是我的,我的还是我的~!)回复于 2005-04-30 19:09:40 得分 2

顶一个  
  Top

49 楼brianlu(-)回复于 2005-04-30 20:23:01 得分 2

markTop

50 楼shazi_pig(傻子)回复于 2005-04-30 20:33:19 得分 2

非常感谢!!收藏!Top

51 楼shazi_pig(傻子)回复于 2005-04-30 20:33:27 得分 2

非常感谢!!收藏!Top

52 楼qifa(DoItNow)回复于 2005-04-30 20:40:13 得分 2

UPTop

53 楼flyarry()回复于 2005-04-30 21:18:41 得分 2

我也收藏...Top

54 楼gumbour(gub不是bug)回复于 2005-04-30 21:32:26 得分 2

收藏  
  学习Top

55 楼haha52(执子之手,敛其半世癫狂;吻子之眸,遮其半世流离)回复于 2005-04-30 21:35:17 得分 2

收藏Top

56 楼sonique(雨季不再来)回复于 2005-04-30 21:51:05 得分 2

非常8错Top

57 楼sankt(宠辱不惊,看庭前花开花落;去留无意,望天空云卷云舒.)回复于 2005-04-30 22:11:35 得分 2

好帖  
  upTop

58 楼zhangfjj(小张)回复于 2005-04-30 22:28:52 得分 2

学习一下Top

59 楼277894613(秒大刀)回复于 2005-04-30 22:34:42 得分 2

收藏了啊,谢谢!!!Top

60 楼virm(查无此人)回复于 2005-04-30 22:40:14 得分 4

太简单了,呵呵  
  这些在汇编里,简直就是常识!  
   
  很多地方可以继续优化啊(位运算自然是为了优化啊)  
   
  -------------------------------------  
  计算绝对值  
  int   abs(   int   x   )    
  {  
  return   -x   &   x   ;  
  }  
  --------------------------------------  
  不使用第三方交换x,y:  
  x^=y^=x^=y;  
   
  ----------------------------------------  
  符号函数:sign(x)   =   -1,   x<0;   0,   x   ==   0   ;   1,   x   >   0  
  int   sign(int   x)  
  {  
  return     -((unsigned(x))>>31   |   (-x)>>31   );//   x=-2^31也不失效  
  }  
   
  还有很多不够精细的,希望大家不要盲信楼主啊  
   
  位技巧一定要自己反复推敲,不可从众,否则精妙之处不能体会又有什么用呢,反而是个累赘  
   
  Top

61 楼YFY(天易)回复于 2005-04-30 22:45:50 得分 2

ding   yi   xia.Top

62 楼virm(查无此人)回复于 2005-04-30 22:49:41 得分 2

以下还用到减法,不知道位运算还有何意义,纯粹搞笑  
   
  doz=x-y,   x>=y;   0,   x<y  
  int   doz(int   x,   int   y   )  
  {  
  int   d   ;  
  d   =   x-y   ;  
  return   d   &   ((~(d^((x^y)&(d^x))))>>31)   ;  
  }  
   
  int   max(int   x,   int   y   )    
  {  
  int   m   ;  
  m   =   (x-y)>>31   ;    
  return   y   &   m   |   x   &   ~m   ;  
  }  
   
  Top

63 楼wadefelix(流浪者幸运)回复于 2005-04-30 23:11:59 得分 2

MarkTop

64 楼du51(郁郁思扬)回复于 2005-04-30 23:22:53 得分 2

晕.一直没进.这么好的东西.  
  UP.收下了.Top

65 楼foochow(无聊,灌水......)回复于 2005-05-01 00:16:33 得分 2

UP不错Top

66 楼yedi_chu(夜帝)回复于 2005-05-01 00:29:50 得分 2

收藏了,以后慢慢吸收~Top

67 楼mostideal(三甲)回复于 2005-05-01 00:59:28 得分 2

dingTop

68 楼abaowu(阿宝)回复于 2005-05-01 01:15:54 得分 2

markTop

69 楼xialin168(林)回复于 2005-05-01 05:02:16 得分 2

markTop

70 楼czj_123(城市稻草人)回复于 2005-05-01 07:58:14 得分 2

dddddddddddddTop

71 楼zwzzj(独学而无友,则孤陋而寡闻. )回复于 2005-05-01 08:05:41 得分 2

不错,收藏.Top

72 楼ericqxg007(还有很多东西要学(卡卡一米阳光))回复于 2005-05-01 08:12:56 得分 2

谢谢Top

73 楼XPR(橡皮人)回复于 2005-05-01 09:40:13 得分 2

启发呀!好贴呀!感谢!Top

74 楼liubingqian(海风)回复于 2005-05-01 09:51:53 得分 2

机械工业出版社《高效程序的奥秘》都是讲位操作的,很不错。Top

75 楼ganbaba(流光飞舞)回复于 2005-05-01 10:34:12 得分 2

支持楼主Top

76 楼starysky(小猪快跑)回复于 2005-05-01 13:09:00 得分 2

markTop

77 楼Mrpapaya(阿木)回复于 2005-05-01 13:45:55 得分 2

 
                                      顶Top

78 楼Mrpapaya(阿木)回复于 2005-05-01 13:46:44 得分 2

<p>   顶   <\p>Top

79 楼luowu(luowu)回复于 2005-05-01 19:41:54 得分 2

hehe    
  真是好人Top

80 楼rabi_(`!懒虫!`)回复于 2005-05-01 20:26:27 得分 2

哇!又送分又送贴,感激涕零!  
   
  还没看,先谢过了!不管经不经典,那么多的东西绝对不赖吧!  
   
  好人哪!倒,把我兴奋的,激动的汗都出了一身了  
   
  谢了谢了!Top

81 楼rabi_(`!懒虫!`)回复于 2005-05-01 20:42:59 得分 2

不小心看到  
   
  查无此人?       是新喜吗?如果不是,认错了,不好意思  
   
  应该不是,新喜很乖的,听讲话口气不太像  
   
  是的话,真是意外了.  
   
  不知道这算不算灌水,啊!别打我!Top

82 楼kobefly(科比--网络学习中)回复于 2005-05-02 11:23:51 得分 1

楼主好人  
   
  再顶一次  
   
  不然就沉了  
   
  让更多的人学习啊Top

83 楼hbyufan()回复于 2005-05-02 11:46:22 得分 1

UPTop

84 楼somedummy(某人马甲)回复于 2005-05-02 12:04:23 得分 1

看了一点  
   
  将最右侧0位改为1位:   x   |   (x+1)  
   
  为啥要这样?直接x|1不就行了?  
   
  而且如果按照上面这个x|(x+1)的话,假设x为111,那么x+1为1000这样的话,产生的就是1111了……  
   
  楼主请多验证再发帖……Top

85 楼arrowcy(长弓手)回复于 2005-05-02 14:36:55 得分 1

upTop

86 楼arrowcy(长弓手)回复于 2005-05-02 14:37:09 得分 1

upTop

87 楼kobefly(科比--网络学习中)回复于 2005-05-02 17:17:00 得分 4

somedummy(某人马甲·C/C++   抢分王·废人认证)   (   )   信誉:100     2005-5-2   12:04:24     得分:   0      
     
     
         
  看了一点  
   
  将最右侧0位改为1位:   x   |   (x+1)  
   
  为啥要这样?直接x|1不就行了?  
   
  而且如果按照上面这个x|(x+1)的话,假设x为111,那么x+1为1000这样的话,产生的就是1111了……  
   
  楼主请多验证再发帖……  
   
       
     
  兄弟,这个问题楼主的意思应该是将一个数2进制中最右的一位0位置为1  
  你所举的例子,111,加一后为1000的话,必然后4位为0111,所以,结果是1111是正确的,将最右边  
  的一个0位置为1了啊  
   
  呵呵Top

88 楼somedummy(某人马甲)回复于 2005-05-02 17:32:43 得分 1

……小样的kobefly……  
   
  你再看看左右……  
   
  再说了,我要是把数字换成了  
  10011呢?+1以后得到10100,然后和x去或,得到的是10111,这个是什么东西……Top

89 楼pahuihui(帕灰灰)回复于 2005-05-04 21:14:02 得分 1

楼主好人!不错!Top

90 楼sun428(Born to Win)回复于 2005-05-04 21:44:22 得分 1

收藏.  
  Top

91 楼zhang_jiang(Solar)回复于 2005-05-04 22:39:52 得分 1

>   10011呢?+1以后得到10100,然后和x去或,得到的是10111,这个是什么东西……  
  10011是负数,+1-->10010   和x或,得到10011Top

92 楼somedummy(某人马甲)回复于 2005-05-05 01:25:13 得分 1

回复人:   zhang_jiang(Solar)   (   )   信誉:100     2005-05-04   22:39:00     得分:   0      
     
     
        >   10011呢?+1以后得到10100,然后和x去或,得到的是10111,这个是什么东西……  
  10011是负数,+1-->10010   和x或,得到10011  
       
     
  ==================================  
  这个就更让我无语了……你见过5位为一个字节或者一个字的平台?Top

93 楼worldnews(想飞就要长翅膀)回复于 2005-05-05 01:46:52 得分 1

如此好贴当然收藏Top

94 楼xinde()回复于 2005-05-05 10:24:08 得分 1

好东西,顶Top

95 楼dobear_0922(do熊)回复于 2005-05-05 12:13:26 得分 1

收藏了,谢谢楼主!Top

96 楼YufengShi(浪子)回复于 2005-05-05 21:37:02 得分 1

位运算虽然效率高,不过可读性可维护性太差,慎用!Top

97 楼zhang_jiang(Solar)回复于 2005-05-06 13:42:08 得分 1

to   somedummy:  
  看错,你继续。。。Top

98 楼winstonch()回复于 2005-05-06 13:54:16 得分 1

markTop

99 楼faaddee(想知道)回复于 2005-05-06 13:58:41 得分 1

学习Top

100 楼copygirl(wa!)回复于 2005-05-06 13:59:24 得分 1

lala,接分喽!Top

101 楼hzmjoe(落叶随风)回复于 2005-05-06 14:43:31 得分 1

学习!!Top

102 楼zharry(行者)回复于 2005-05-06 19:34:58 得分 1

收藏Top

103 楼zjlang(阿亮)回复于 2005-05-06 20:36:51 得分 1

200的分数怎么办啊??呵呵Top

104 楼Audi_TT(人不嚣张枉少年)回复于 2005-05-06 21:02:01 得分 1

markTop

105 楼zouwen198317(静悄悄)回复于 2005-05-06 21:11:31 得分 1

帮顶Top

106 楼Marbloro(【寒→轩】)回复于 2005-05-06 23:25:54 得分 1

up~!  
  Top

107 楼hjt28(hjt)回复于 2005-05-07 00:15:46 得分 1

顶!!!  
   
   
  Top

108 楼DuoFG(多非光)回复于 2005-05-07 03:24:08 得分 1

学习Top

109 楼xuelong_zl(点雨点[我身上咋就没MM的香水味涅??#-_-])回复于 2005-05-07 17:38:02 得分 1

我不会,就不说话了Top

110 楼dzw2004(深蓝)回复于 2005-05-07 22:35:59 得分 1

up~Top

111 楼superslash(开始用功学习)回复于 2005-05-08 03:10:21 得分 1

看看先Top

112 楼lbaby(春天来了...)回复于 2005-05-08 06:16:11 得分 1

 
  很多办法是基于int是32位的假设的,  
   
  64位马上要普及,移植时要小心  
  Top

113 楼baojian88888(机器人)回复于 2005-05-08 08:20:14 得分 1

不错,markTop

114 楼wzjasj(爱尔兰咖啡(闭关·与世隔绝))回复于 2005-05-08 08:30:48 得分 1

收藏+学习Top

115 楼dq2004(替补一号)回复于 2005-05-08 08:48:07 得分 1

收藏Top

116 楼Cnwanglin(你们太有才了)回复于 2005-05-08 09:12:30 得分 1

谢谢!帮顶Top

117 楼QunKangLi(心里面疼得有点发酸 一定是有雾来了 打湿了我的眼眶)回复于 2005-05-08 09:16:47 得分 0

这是某位前辈的忠告,结帐临别之际,与大家共勉之...  
   
  以前总以为技巧最重要,现在才知道简单的才是好的  
  为实现功能而写的代码我们要留着  
  为自己准备一个笔记本、一只笔  
  代码一定要规范  
  做一个虚心的人  
  做一个不保守的人  
  Top

相关问题

  • 走过路过不要错过!!!
  • 走过,路过但是不能错过!!!!
  • 走过路过,不要错过了!
  • 路过,走过,千万不要错过!!!
  • 走过路过不要错过阿
  • 走过,路过,不要错过!!!
  • 黄金百两问个路,高手走过路过别错过!
  • 高手大侠们走过路过别错过。。。
  • 走过,路过不要错过,进的都给分
  • 千古奇观:走过路过,千万不要错过!

关键词

  • 函数
  • 原型
  • 代码
  • 参数
  • 个数
  • argp
  • 形式参数
  • va
  • 调用
  • 省略号

得分解答快速导航

  • 帖主:QunKangLi
  • useresu
  • kiko_lee
  • qrlvls
  • qrlvls
  • laiyiling
  • yjm0105
  • chunhai12
  • Roaming_Sheep
  • junguo
  • yunlang2233187
  • lightning8
  • akindo
  • heskyII
  • vcleaner
  • kugou123
  • wwxsoft
  • NewWriter
  • MTring
  • mbcw
  • galanz
  • kobefly
  • Enirax
  • homtipo
  • Audi_TT
  • pomelowu
  • flying_dancing
  • zhang_jiang
  • wodeyouxian
  • DigNet
  • lanphaday
  • avalonBBS
  • viyar
  • fhvk
  • zhousqy
  • dongfa
  • oo
  • rwdx
  • mefit
  • ltc_mouse
  • liujingfu123
  • y39242
  • zixiu2008
  • abcabc999
  • tfq
  • niuman
  • lzwei3842
  • jk88811
  • brianlu
  • shazi_pig
  • shazi_pig
  • qifa
  • flyarry
  • gumbour
  • haha52
  • sonique
  • sankt
  • zhangfjj
  • 277894613
  • virm
  • YFY
  • virm
  • wadefelix
  • du51
  • foochow
  • yedi_chu
  • mostideal
  • abaowu
  • xialin168
  • czj_123
  • zwzzj
  • ericqxg007
  • XPR
  • liubingqian
  • ganbaba
  • starysky
  • Mrpapaya
  • Mrpapaya
  • luowu
  • rabi_
  • rabi_
  • kobefly
  • hbyufan
  • somedummy
  • arrowcy
  • arrowcy
  • kobefly
  • somedummy
  • pahuihui
  • sun428
  • zhang_jiang
  • somedummy
  • worldnews
  • xinde
  • dobear_0922
  • YufengShi
  • zhang_jiang
  • winstonch
  • faaddee
  • copygirl
  • hzmjoe
  • zharry
  • zjlang
  • Audi_TT
  • zouwen198317
  • Marbloro
  • hjt28
  • DuoFG
  • xuelong_zl
  • dzw2004
  • superslash
  • lbaby
  • baojian88888
  • wzjasj
  • dq2004
  • Cnwanglin

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo