笔记一下二进制在程序中的应用
来源:互联网 发布:艺萌微信投票系统源码 编辑:程序博客网 时间:2024/06/03 21:33
运算符含义
>>
右移 表示将a的各二进制位右移N位,移到右端的低位被舍弃,对无符号数,高位补0。运算符运算
常用二进制数
运算符的应用:
- 判断奇偶性:
bool Parity(Type value) { if(value & 0x0001 == 0) return false; else return true; } //加以优化: template<class Type> inline bool Parity(Type value) { return (value & 1 != 0); }
- 是否是2的二次方:
bool is_pow2(int x) //判断是否2的n次方 { x &= x-1; if(!x) return true; return false;}可以写成 return ( (x&(x-1))==0) && (x!=0);
- 计算绝对值:
abs( x ) { y=x>>31 ; return(x^y)-y;//也可写作 (x+y)^y }
- 补码运算公式:
-x = ~x + 1 = ~(x-1)~x = -x-1-(~x) = x+1~(-x) = x-1x+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)+yx&y = (~x|y)-~xx==y: ~(x-y|y-x)x!=y: x-y|y-xx< 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 average(int x, int y) //返回X、Y的平均值 { return (x & y) + ( (x^y)>>1 ); //x&y 取出x和y二进制都为 1 的所有位,这是x、y都为 1 的部分,因为相同,所以直接加就行了 //x^y x和y中有一个为 1 的所有位 //后者是x为 1,y为 0的部分,以及y为 1,x为 0 的部分,两部分加起来除以2,然后跟前面的相加就可以了 }
- 不用临时变量交换两个数:
void swap(int x , int y) { x ^= y; y ^= x; x ^= y; } 如果x=7,y=8,x^=y>>7^=8,x=15,y=8y^=x>>8^=15,x=15,y=7x^=y>> x^=y,x=8,y=7
- 常用运算(在不产生溢出的情况下):
取模运算转化成位运算a % (2^n) 等价于 a & (2^n - 1)乘法运算转化成位运算a * (2^n) 等价于 a<< n除法运算转化成位运算 a / (2^n) 等价于 a>> n 例: 12/8 == 12>>3 a % 2 等价于 a & 1 if (x == a) x= b; else x= a;等价于 x= a ^ b ^ x;
- 统计数字二进制中1的个数:
朴素的统计办法是:先判断n的奇偶性,为奇数时计数器增加1,然后将n右移一位,重复上面步骤,直到移位完毕。
博客出处
template<class Type> inline bool Parity(Type value) { return (value % 2 != 0); } template<class Type> inline int CountOne(Type value) { if(value != 0) { return Parity(value) + CountOne(value >> 1); } return 0; }
另一种统计方法:32位无符 号数的1的个数可以这样数:
int CountOne(unsigned long n) { //0xAAAAAAAA,0x55555555分别是以“1位”为单位提取奇偶位 n = ((n & 0xAAAAAAAA) >> 1) + (n & 0x55555555); //0xCCCCCCCC,0x33333333分别是以“2位”为单位提取奇偶位 n = ((n & 0xCCCCCCCC) >> 2) + (n & 0x33333333); //0xF0F0F0F0,0x0F0F0F0F分别是以“4位”为单位提取奇偶位 n = ((n & 0xF0F0F0F0) >> 4) + (n & 0x0F0F0F0F); //0xFF00FF00,0x00FF00FF分别是以“8位”为单位提取奇偶位 n = ((n & 0xFF00FF00) >> 8) + (n & 0x00FF00FF); //0xFFFF0000,0x0000FFFF分别是以“16位”为单位提取奇偶位 n = ((n & 0xFFFF0000) >> 16) + (n & 0x0000FFFF); return n; } 再来一种:int bitCount(int x) { // 把32位划分为8部分,每部分4位。使用掩码0x11111111来获得每部分的最后一位。 int mask = 0x11 + (0x11 << 8) + (0x11 << 16) + (0x11 << 24); // 通过右移、相加,来计数每一部分中1的数量。 int seg8Count = (x & mask) + ((x >> 1) & mask) + ((x >> 2) & mask) + ((x >> 3) & mask); int seg4Count1 = seg8Count + (seg8Count >> 8); int seg4Count2 = (seg8Count >> 16) + (seg8Count >> 24); // 为了处理相加后的进位问题,我们需要与0x0F进行位与运算,只保留每部分最后4位。 int result = (seg4Count1 & 0x0F) + ((seg4Count1 >> 4) & 0x0F) + (seg4Count2 & 0x0F) + ((seg4Count2 >> 4) & 0x0F); return result;}
- 取非:
int negate(int x) { return ~x + 1;}
- 果所有偶数位都是1,则返回1:
int allEvenBits(int x) { // 把32位划分为4部分,每部分8位。每部分都互相进行位与运算,再和0x55进行位与运算,取偶数位。 // 当且仅当所有偶数位都是1,位与运算的结果才是0x55。然后加上0xAB,将进位变为0x100。 // 如果有偶数位不是1,那么结果必然小于0x55,加上0xAB后,也会小于0x100。 // 因此,这两种情况的区别就在于从右往左数第9位. 右移该位得到最后结果。 int y; int result = 0; y = x & (x >> 16); y = y & (y >> 8); result = ((y & 0x55) + 0xAB) >> 8; return result;}
- x是否大于y:
int isGreater(int x, int y) { // 如果x是非负数,y是负数,则flag的标志位为1。在此情况下,x一定大于y。 int flag1 = (~x) & y; // 如果x,y的标志位相同,则flag2的标志位为0。需要进一步比较。 // 如果x,y相等,则flag==0。 int flag2 = x ^ y; // 如果x,y的标志位相同,则不可能发生溢出,除非x,y都是0x80000000。 // 对于x,y都是0x80000000的特殊情况,可以使用x!=y来判断。 // 如果x>y,他们差的标志位将会是0。 int difference = x + (~y + 1); // 只有以下2种情况,result会是1: // 1. flag1是1 (x是非负数,y是负数) // 2. x, y同正负, 并且x-y>=0, 并且x!=y. int result = ((flag1 | ~(flag2 | difference)) >> 31) & 0x01 & !!flag2; return result;}
- 系统中权限应用:
设各权限值分别如下(2倍等比递增的关系):
1. 列表/查看 = 2
2. 新增 = 4
2. 修改 = 8
4. 删除 = 16
若某个(Role + Module)拥有查看、新增、修改、删除的权限,则其Permission=2+4+8+16=30。
判断Permission是否包含“查看”的权限值,就用 if((Permission & 2) == 2)
判断Permission是否包含“新增”的权限值,就用 if((Permission & 4) == 4)
判断Permission是否包含“修改”的权限值,就用 if((Permission & 8) == 8)
判断Permission是否包含“删除”的权限值,就用 if((Permission & 16) == 16)
- 图像中颜色应用:
颜色RGB值,我们在这里谈24位颜色。也就是RGB中的R(红)、G(绿)、 B(蓝)分别占8位
a << 24 1111 1111 0000 0000 0000 0000 0000 0000r << 16 0000 0000 1111 1111 0000 0000 0000 0000g << 8 0000 0000 0000 0000 1111 1111 0000 0000b 0000 0000 0000 0000 0000 0000 1111 1111
32位颜色除了RGB,还有一个A,即透明度
获取ARGB值:
var color:uint = 0xff342388; var a:uint = color >>> 24 //注意这里是>>>,无符号右移位操作,右移24位,把342388移出,得到0xff //也可表示为:((color >> 24) & 255); var r:uint = color >> 16 & 0xff;//右移16位,把2388移出,取0x34 var g:uint = color >> 8 & 0xff;//右移8位,把88移出,得0x3423,与0xff按位与操作,得0x23 var b:uint = color & 0xff;//得到0x88
生成颜色值:
public static int ToArgb(this Color color) { int argb = color.A << 24; argb += color.R << 16; argb += color.G << 8; argb += color.B; return argb;}
博客出处
- 游戏中角色状态应用:
假设游戏状态如下:
enum EPLAYER_STATE { EPST_NONE = 0x00000000, // 没有状态 EPST_ADDHP = 0x00000001 , // 加血 EPST_ADDMP = 0x00000002, // 加蓝 EPST_ADDSP = 0x00000004, // 加体力 EPST_JMDAM = 0x00000008, // 经脉受伤 EPST_DIANX = 0x00000010, // 被点穴 EPST_XUANY = 0x00000020, // 被眩晕 EPST_ATTCK = 0x00000040, // 被攻击 // ... ... // 最多可以写32个状态,已经足够了。为什么是32,因为一个32位整数来存放的。 };
初始状态:
UINT dwPlayerState = EPST_NONE;
假如我要同时加上几个状态的话。那么:
dwPlayerState |= ( EPST_ADDMP| EPST_ADDSP| EPST_JMDAM );
如果我要清掉状态:
// 清除蓝药状态dwPlayerState &= ~EPST_ADDMP; // 这样便清掉了。// 清除多个状态 dwPlayerState &= ~( EPST_ADDMP| EPST_ADDSP| EPST_JMDAM );
参考,参考,参考,参考,参考,参考,参考,参考,参考,参考,参考,参考
0 0
- 笔记一下二进制在程序中的应用
- 二进制计算在编程(JAVA)中的应用
- 二进制在权限系统中的应用
- 数理逻辑在程序中的应用
- 探讨一下分布式结构在网络应用中的种种好处
- CHM帮助文件在VB程序中的应用
- 人工智能在围棋程序中的应用
- 状态模式在绘图程序中的应用
- CHM帮助文件在VB程序中的应用
- Ping程序在TCP/IP中的应用
- CHM帮助文件在VB程序中的应用
- 结构在C程序中的应用
- PendingIntent在AppWidget程序中的应用
- 正则在小偷程序中的应用
- & | ^ << >> 操作符在程序中的应用
- 正则在小偷程序中的应用(续)
- PendingIntent在AppWidget程序中的应用
- PendingIntent在AppWidget程序中的应用
- 应用Sift算子的模式识别方法 内核篇
- iOS 常用的第三方框架
- Splash/Welcome的作用
- 二维树状数组 —— POJ 2155 Matrix
- Sublime Text 3 常用插件以及安装方法(转)
- 笔记一下二进制在程序中的应用
- js比较日期字符串
- 找出字符串中第一个只出现一次的字符
- mysql 创建测试大表
- java环境安装完毕,运行web项目报javax annotation managedbean unsup错误
- VS2010下,C++调用python的设置
- iOS分享(一) shareSDK
- 使用libjpeg库实现jpeg图片的缩放(缩略图)
- plat_button应用程序