位运算是指进行二进制位的运算,这里主要贴一些例子代码,仅供参考。
一、“按位与”运算符(&)的应用。
- /*
- * 按位与:
- * 参加 & 运算的若为正数,则直接按照正数的补码运算。
- * 参加 & 运算的若为负数,则会把负数表示为补码形式,然后参加运算。
- * 特殊用途:清零;取一个数中某些指定位;保留指定位。
- */
- void bitAnd() {
- printf("=== Bit And Operator Begin... ===\n");
- // 3 00000011
- // 5 00000101
- // 3&5 00000001 = 1
- printf("\t3 & 5 = %d\n", 3&5);
- // -3 11111101
- // -5 11111011
- // -3&-5 11111001 = -7
- printf("\t-3 & -5 = %d\n", -3&-5);
- printf("=== Bit And Operator End. ===\n\n");
- }
二、“按位或”运算符(|)的应用。
- /*
- * 按位或:
- * 特殊用途:对某一个数据的指定位定值为 1。
- * 例如:a | 0377 或者 a | B,则值a的高八位保留原样,低八位则置为 1。
- */
- void bitOr() {
- printf("=== Bit Or Operator Begin... ===\n");
- // a 10100011
- printf("\t3 | 5 = %d\n", 3|5);
- printf("=== Bit Or Operator End. ===\n\n");
- }
三、“按位异或”运算符(^)的应用。
- /*
- * 按位异或:
- * 特殊用途:与1相^,反转原值;与0相^,保留原值;交换两个值,不用临时变量。
- */
- void bitXor() {
- printf("=== Bit XOR Operator Begin... ===\n");
- int a = 3;
- int b = 5;
- printf("\tBefore XOR Operator: a = %d, b = %d.\n", a, b);
- a = a ^ b;
- b = b ^ a;
- a = a ^ b;
- printf("\tAfter XOR Operator: a = %d, b = %d.\n", a, b);
- printf("=== Bit XOR Operator End. ===\n\n");
- }
四、“取反”运算符(~)的应用。
特别注意:~的优先级比算术运算符,关系运算符,逻辑运算符和其它运算符都高。
五、“左移”运算符(<<)的应用。
- /*
- * 左移:
- * 特别注意:<<高位左移后移除,舍弃;左移一位相当于原数乘以2;左移比乘法运算快的多。
- */
- void bitLeftShift() {
- printf("=== Bit Left Shift Operator Begin... ===\n");
- int a = 15;
- printf("\tBefore Left Shift Operator: a = %d\n", a);
- a = a << 2;
- printf("\tAfter Left Shift Operator: a = %d\n", a);
- printf("=== Bit Left Shift Operator Begin... ===\n\n");
- }
六、“右移”运算符(>>)的应用。
- /*
- * 右移:
- * 特别注意:>>低位右移后移除,舍弃,高位补0还是1,看情况;右移一位相当于原数除以2。
- * 右移时,需要特别注意符号问题。对无符号数,右移时左侧高位移入0;对于有符号数,
- * 如果原来符号位为0(该数为正),则左侧移入0。如果符号位为1(该数为负),则左侧
- * 移入 0 还是 1,要取决于所用的计算机系统。有的系统移入 0,称为“逻辑右移”;
- * 有的系统移入 1,称为“算术右移”。C编译器常用的是算术右移。
- */
- void bitRightShift() {
- printf("=== Bit Right Shift Operator Begin... ===\n");
- int a = 40;
- printf("\tBefore Right Shift Operator: a = %d\n", a);
- a = a >> 2;
- printf("\tAfter Right Shift Operator: a = %d\n", a);
- printf("=== Bit Right Shift Operator Begin... ===\n\n");
- }
下面是一些 Demo:
- /* 取一个整数 a 从右端开始的 4-7 位 */
- /* 分析:取从右端开始的 4-7 位,从第 0 位开始计数,所以数 a 的最右端 4 位不取,
- * 从第 4 位开始取位,4-7 一共要取 4 个位,一直取到第 8 位,。
- */
- void Demo_01() {
- printf("========== Test Demo_01 ===========\n");
- // 方法一:先把 a 右移 4 位;设置一个低 4 位为 1,其它位全为 0 的数;再做 &。
- unsigned a, b, c, d;
- scanf("%o", &a);
- b = a >> 4;
- c = ~(~0 << 4);
- d = b & c;
- printf("%o, %d\n%o, %d\n", a, a, d, d);
- // 方法二:直接设置一个数,取出 4-7 位,如:11110000,即0360,用;然后右移四位。
- unsigned e;
- scanf("%o", &a);
- printf("Input 360,即11110000 ==> ");
- scanf("%o", &e);
- printf("%o, %d\n%o, %d\n", a, a, (a & e) >> 4, (a & e) >> 4);
- }
- // 循环移位。将数 a 进行右循环移位,移动 n 位,右侧的 n 位移动到左侧。
- /* 方法:将数 a 的右侧 n 位放入另外一个变量;把 a 右移 n 位; 再做 |。
- */
- void Demo_02() {
- printf("========== Test Demo_02 ===========\n");
- unsigned a, b, c, d;
- int n;
- scanf("a=%o,n=%d", &a, &n);
- b = a << (16-n);
- c = a >> n;
- d = b | c;
- printf("%o, %d\n%o, %d\n", a, a, d, d);
- }
- // 变量 data,假设 a,b,c,d 分别占data的 2位、6位、4位、4位,将 c 的值变为 12。
- void Demo_03() {
- printf("========== Test Demo_03 ===========\n");
- unsigned data, result, temp;
- scanf("data=%x", &data);
- // result = data & 0xff0f;//方法一
- result = data & (~(15 << 4));//方法二
- temp = 12;
- temp = (temp & 15) << 4;
- result = result | temp;
- printf("%x, %d\n", result, result);
- }
- /* Define Function
- * By 郎图腾
- */
- /* 取出一个16位数的奇数位函数。*/
- unsigned getOddbits(int a) {
- return (0xaaaa & a);
- }
- /* 求得原码的补码函数getComplement(a) */
- void getComplement(int a) {
- printf("== 求得原码的补码函 ==\n");
- printf("Input a(10) = %d, a(16) = %x\n", a, a);
- printf("The Complement is %x\n", ~a+1);
- }
- /* 循环移位函数move(a, n) */
- void move(int a, int n) {
- printf("== 循环移位函数move(a, n) ==\n");
- if (0 == a) {
- printf("0再移位,还是个0,还是算了,别移了!\n");
- } else {
- printf("n = %d\n", n);
- printf("== n > 0 时右移位,n < 0时左移位。==\n");
- unsigned b, c, d;
- if (n > 0) {
- b = a << (32-n);
- c = a >> n;
- d = b | c;
- printf("数 %d 右移 %d 位后的值为:%d\n", a, n, d);
- } else {
- n = -n;
- b = a >> (32-n);
- c = a << n;
- d = b | c;
- printf("数 %d 左移 %d 位后的值为:%d\n", a, n, d);
- }
- }
- }