C#的一个好处就是几乎完全不用与二进制有关的东西和内存打交道,一切都是对象,一切都是十进制。突然转到C++,有点无所适从。现在记录一下半个月集中学习C++和DirectX的一些经验。
1、或运算(Or)符号:“|” ,与运算(And)符号:“&”。
在Window7系统自带计算器的程序员模式下可以找到这两个运算符。Windows7的计算器相当好用,输入的任何数都可以直观的表示出对应的二进制转换。
在C#中我们知道:
1 | 0 = 1
0 | 1 = 1
1 | 1 = 1
1 & 0 = 0
0 & 1 = 0
1 & 1 = 1
可以总结为:
与运算:两个数只要有一个为零则为零。
或运算:两个数只要有一个为一则为一。
这一法则不仅适用0和1,而且适用于任何数。
任意两个数 458 和 921 对应的二进制转换为:111001010,,1110011001。
运用上述法则:
0111001010 &
1110011001 =
0110001000
0111001010 |
1110011001 =
1111011011
以上是基础知识。
DirectX中有许多方法的参数名类似 xxFlag之类的东西。这时可以传入一些常量的或运算组合。比如:
lpdd->SetCooperativeLevel(main_window_handle,
DDSCL_ALLOWMODEX | DDSCL_FULLSCREEN |
DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT);
这种方法很有智慧,这些常量的值转换为二进制并进行与运算后就可以在一个数里面存储多个信息,比如
DDSCL_ALLOWMODEX = 1; //二进制:0001
DDSCL_FULLSCREEN = 2; //二进制:0010
DDSCL_EXCLUSIVE = 4; //二进制:0100
DDSCL_ALLOWREBOOT = 8; //二进制: 1000
OK,接下来把这四个选项进行与运算
0001
0010
0100
1000
= 1111
任意数量的选项的任意组合都不会重复,而且非常容易判断是否包含一个值.
判断方法就是用到与运算
int group = DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT;
现在我想判断 group里是否有包含DDSCL_EXCLUSIVE .
if (group & DDSCL_EXCLUSIVE)
{
//包含
}
else
{
//不包含
}
原理很简单.
DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT =
0100 |
1000 =
1100
1100 &
0100 =
0100 != 0 则为true
1100 &
1000 =
1000 != 0 则为true
而我们拿这个值和一个不包含在这个值里的数字进行与运算:
1100 &
0010 =
0000 = 0 则为false
2、移位运算符
左移: <<
右移:>>
很形象,很直观。
左移就是把一个数的二进制转换向左移动指定的位数。比如一个数
11111 << 1
把数11111向左移一位
结果为: 111110
同样的道理,把11111向右移一位
11111 >> 1
结果为: 1111
从二进制的角度来看十分简单.但如果转换到十进制就会有点困惑了.
其实从十进制角度来看也是有一规律的.
11111的十进制转换为31,左移一位的结果为62,左移两位的结果为124,左移三位的结果为:248.
规律出来了,左移1位等于乘以2,左移两位等于乘以2再乘以2,左移三位等于乘以2乘以2再乘以2
即左移位结果等于被移位数乘以2的移位数次方.
反过来右移就是做除法了.即右移位结果等于被移位数除以2乘以移位数次幂