我的C实践(4):基本操作的位运算实现
2010-03-28 21:20
435 查看
下面使用位运算来实现一些基本的操作和基本的函数,这些实现全部都是宏,这是高效率的关键。
/* base.h:基本操作的位运算实现 */ #ifndef BASE_H #define BASE_H #define word int #define uword unsigned int /* 将最右侧的1位改成0位 */ #define right1to0(x) ((x)&((x)-1)) /* 向右传播最右侧的1位 */ #define right1torig(x) ((x)|((x)-1)) /* 将最右侧的连续1位串改成0位串 */ #define right1sto0s(x) (((x)|(x)-1)+1 & (x)) /* 检查无符号整数x是否为2的幂,注意&的优先级低于==,需要括号 */ #define powof2u(x) (((x)&((x)-1))==0) /* 检查无符号整数x是否为2**n-1的形式 */ #define pow2sub1u(x) (((x)&((x)+1))==0) /* 检查无符号整数x是否为2**j-2**k形式 */ #define pow2subpow2u(x) ((((x)|(x)-1)+1 & (x))==0) /* 下列掩码直接析出字中指定的位 */ /* 析出最右侧的1位 */ #define right1(x) ((x) & -(x)) /* 析出最右侧的0位 */ #define right0(x) (~(x)&((x)+1)) /* 析出后缀0 */ #define suffix0(x) (((x)&-(x))-1) /* 析出最右侧的1位和后缀0(即后缀10...0) */ #define suffix10s0(x) ((x) ^ (x)-1) /* 下列掩码与字做&运算,可以析出字中指定的字段 */ /* 析出高阶n位(注意n的值不能大于int型的宽度) */ #define high_ones(n) (-1<<32-(n)) /* 析出低阶n位 */ #define low_ones(n) (~(-1<<(n))) /* 析出低阶offset位和高阶32-offset-width位 */ #define mid_zeros(width,offset) / (-1<<(width)+(offset) | ~(-1<<(offset))) /* 析出中间width位,它右侧有offset位 */ #define mid_ones(width,offset) / (~(-1<<(width)+(offset)) & (-1<<(offset))) /* 对无符号整数x,求比x大且与x中的位1个数相同的下一个整数: 例如对nnn0 1111 0000,则下一个整数为nnn1 0000 01111。 可以用这个函数来遍历一个集合的所有子集 */ #define nextsame1u(x) (right1(x)+(x) | / (((x)^right1(x)+(x))>>2)/right1(x)) /* 字的绝对值函数:注意x>>31为0或-1,而x^0=x,x^-1=~x */ #define abs(x) (((x)^((x)>>31))-((x)>>31)) /* 绝对值的负值 */ #define nabs(x) (((x)>>31)-((x)^((x)>>31))) /* 符号扩展:将第7位向左传播(位编号从0开始) */ #define prop7thtolef(x) ((((x) & 0x000000FF) ^ 0x00000080)-0x00000080) /* 对无符号整数实现算术右移:也可用更简单的((signed)(x)>>n) */ #define arithrshiftu(x,n) ((((x)^0x80000000)>>(n))-(0x80000000>>(n))) /* 对有符号整数实现逻辑右移:也可用更简单的((unsigned)(x)>>n) */ #define logicrshift(x,n) ((((x)^0x80000000)>>(n))+(1<<31-(n))) /* 符号函数:x>0返回1,x=0返回0,x<0返回-1 */ #define sign(x) (((x)>0)-((x)<0)) /* 三值比较函数:x>y返回1,x=y返回0,x<y返回-1 */ #define cmp(x,y) (((x)>(y))-((x)<(y))) /* 符号传递函数:返回采用y的符号后的x */ #define copysign(x,y) ((abs(x)^((y)>>31))-((y)>>31)) /* 比较谓词:带符号整数 */ #define equal(x,y) (~((x)-(y)|(y)-(x))>>31) #define noteq(x,y) (((x)-(y)|(y)-(x))>>31) #define less(x,y) ((((x)^(y)) & ((x)-(y)^(x)) ^ (x)-(y))>>31) #define larger(x,y) ((((y)^(x)) & ((y)-(x)^(y)) ^ (y)-(x))>>31) #define lesseq(x,y) ((((x)|~(y)) & ((x)^(y) | ~((y)-(x))))>>31) #define largereq(x,y) ((((y)|~(x)) & ((y)^(x) | ~((x)-(y))))>>31) /* 比较谓词:无符号整数 */ #define equalu(x,y) (~((x)-(y)|(y)-(x))>>31) #define notequ(x,y) (((x)-(y)|(y)-(x))>>31) #define lessu(x,y) ((~(x) & (y) | ~((x)^(y)) & (x)-(y))>>31) #define largeru(x,y) ((~(y) & (x) | ~((y)^(x)) & (y)-(x))>>31) #define lessequ(x,y) (((~(x)|(y)) & (((x)^(y)) | ~((y)-(x))))>>31) #define largerequ(x,y) (((~(y)|(x)) & (((y)^(x)) | ~((x)-(y))))>>31) /* 溢出检测:带符号运算 */ #define addovf(x,y) ((~((x)^(y))&(((x)+(y))^(x)))>>31) #define subovf(x,y) ((((x)^(y))&(((x)-(y))^(x)))>>31) #define mulovf(x,y) ((y)<0 && (x)==0x80000000 || (y)!=0 && (x)*(y)/(y)!=(x)) #define divovf(x,y) ((y)==0 || (x)==0x80000000 && (y)==-1) /* 溢出检测:无符号运算 */ #define addovfu(x,y) (~(x)<(y)) /* 也可用less(~(x),y) */ #define subovfu(x,y) ((x)<(y)) /* 也可用less(x,y) */ #define mulovfu(x,y) ((y)!=0 && (x) > 0xffffffff/(y)) #define divovfu(x,y) ((y)==0) /* 循环移位:带符号整数 */ /* 循环左移n位 */ #define rotlshift(x,n) ((x)<<(n) | (unsigned)(x)>>32-(n)) /* 循环右移n位 */ #define rotrshift(x,n) ((unsigned)(x)>>(n) | (x)<<32-(n)) /* 循环移位:无符号整数 */ #define rotlshiftu(x,n) ((x)<<(n) | (x)>>32-(n)) #define rotrshiftu(x,n) ((x)>>(n) | (x)<<32-(n)) /* 正差函数:x>=y时返回x-y,x<y时返回0。注意&优先级高于^,无需要括号 */ #define doz(x,y) ((x)-(y)&~((x)-(y)^((x)^(y))&((x)-(y)^(x)))>>31) /* 大值函数 */ #define max(x,y) ((y)+doz(x,y)) /* 小值函数 */ #define min(x,y) ((x)-doz(x,y)) /* 下面是无符号版本 */ #define dozu(x,y) ((x)-(y)& arithrshiftu(((x)|~(y))&((x)^(y)|~((x)-(y))) ,31)) #define maxu(x,y) ((y)+dozu(x,y)) #define minu(x,y) ((x)-dozu(x,y)) /* 交换变量的值 */ #define swap(x,y) / do { x=x^y; y=y^x; x=x^y; } while(0) /* 根据掩码来交换变量的相应字段: 当m的第i位为1时,交换x,y的第i位;当m的第i位为0时,保留x,y的第i位不变 */ #define swapbits(x,y,m) / do { x=x^y; y=y^(x&(m)); x=x^y; } while(0) /* 2个常量的循环赋值:当x为a时赋值b,当x为b时赋值a */ #define rottwo(x,a,b) do{ x=(a)^(b)^x; }while(0) /* 3个常量的循环赋值 */ #define rotthree(x,a,b,c) / do{ x=(-(x==c)&(a-c))+(-(x==a)&(b-c))+c; }while(0) #endif
相关文章推荐
- 我的C实践(4):基本操作的位运算实现
- 数据结构笔记(一)线性表的顺序表示和基本操作及其顺序表实现的集合运算(A-B)U(B-A)实例
- 数据结构实践项目——图的基本运算及遍历操作
- 第四周《C语言及程序设计》实践项目26 实现线性表基本操作的函数
- 类模板实现复数运算的基本操作
- 基本操作的位运算实现
- /*顺序查找的基本运算与实现*/
- c# 抽象方法:实现两个数的加、减、乘操作运算
- 单链表及其基本操作的实现
- 第十周:二叉树的基本运算及其实现
- scala学习:List的基本操作实战与基于模式匹配的List排序算法实现
- 数据结构 P62-62 算法实现 单链队列的创建及基本操作
- 数据结构(C语言实现) - 二叉树的基本操作(建立,遍历,结点数,叶子结点数,高度,按树状打印,输出叶子结点等)
- Dao接口实现基本的数据库操作。增删改查
- Java实现二叉树的基本操作
- Unreal 入门-创建人物,实现基本走、跑、跳操作。
- 对链表的基本实现和各种操作
- 实现基本运算
- C语言实现栈的基本操作
- 栈的基本操作实现-c/c++