Java中关于位运算的面试题
位运算的效率是最高的,因为位位运算是直接对二进制进行操作
位运算只能应用于整型和char类型(char类型可以看做是特殊的无符号的整形)
面试题:
a: 判断一个数是否是奇数 a & 1 == 1;
b: 对2 ^ n 取余。 a & (2^n - 1);
c: 如何判断一个数是否是2^n a & (a-1) == 0;
d: 两个整数之间的交换;
e: 用最有效率的方式求2 * 8的值 2 << 3;
a: 判断一个数是否是奇数 a & 1 == 1;
/* 判断一个数是否是奇数? 特点:最低位为1. a & 1 == 1; */ class OperatorDemo1 { public static void main(String[] args) { int a = -2018; // System.out.println(a % 2 == 1); // System.out.println(a % 2 != 1); System.out.println((a & 1) == 1); } }
b: 对2 ^ n 取余。 a & (2^n - 1);
/* 对2的n次幂取余,都可以转换成位运算。 2^n: 1101 1101 % 0100 0000 1101 1101 & 0011 1111 */ class OperatorDemo3 { public static void main(String[] args) { int a = 2019; System.out.println(a % 64); System.out.println(a & (64 - 1)); /*System.out.println(a % 78); System.out.println(a & (78 - 1));*/ } }
c: 如何判断一个数是否是2^n
a & (a-1) == 0;
/* 判断一个数是否是2的n次幂? 2^n:因子都是2; 时间复杂度:logn; 能否在常量时间复杂度内, 判断一个数是否是2的n次幂。 2^n的存储特点:只有一个1,后面全部是0. (a & (a - 1)) == 0 0100 0000 & 0011 1111 0000 0000 0101 0000 & 0100 1111 0100 0000 */ class OperatorDemo4 { public static void main(String[] args) { int a = 1024; System.out.println((a & (a - 1)) == 0); } }
d: 两个整数之间的交换;
/* 面试题 两个整数变量的交换. */ class OperatorDemo5 { public static void main(String[] args) { // 方式一 /*int a = 4; int b = 3; System.out.println("a=" + a + ", b=" + b); int temp = a; a = b; b = temp; System.out.println("a=" + a + ", b=" + b);*/ // 方式二 // 加法和减法互为逆运算。 /*int a = 4; int b = 3; System.out.println("a=" + a + ", b=" + b); a = a + b; // a = 4 + 3, b = 3; b = a - b; // a = 4 + 3, b = 4 + 3 - 3 = 4; a = a - b; // a = 4 + 3 - 4 = 3, b = 4; System.out.println("a=" + a + ", b=" + b);*/ // 方式三 /*int a = 4; int b = 3; System.out.println("a=" + a + ", b=" + b); a = a ^ b; // a = 4 ^ 3, b = 3 b = a ^ b; // a = 4 ^ 3, b = 4 ^ 3 ^ 3 = 4; a = a ^ b; // a = 4 ^ 3 ^ 4 = 3, b = 4; System.out.println("a=" + a + ", b=" + b);*/ // 方式四 int a = 4; int b = 3; System.out.println("a=" + a + ", b=" + b); /*a = a ^ b; b = b ^ a; a = a ^ b; */ // a ^= b ^= a ^= b; a = (a ^ b) ^ (b = a); //工作中千万别这样写, 太show了。写代码,简洁易懂。 System.out.println("a=" + a + ", b=" + b); } }
e: 用最有效率的方式求2 * 8的值 2 << 3;
/* << 左移: 低位补0,高位丢弃 >> 右移: 高位补符号位, 低位丢弃 >>>无符号右移: 高位补0,低位丢弃 注意事项; 左移:左移n个单位,相当于乘以2^n; 右移: 右移n个单位,相当于除以2^n; 对于移位运算符来说,当操作数超出了字长时,实际移动 n mod 字长 个单位。 练习: 用最有效率的方式写出计算2乘以8的结果 2 << 3 */ class OperatorDemo7 { public static void main(String[] args) { int a = 192; System.out.println(a << 2); // 192 * 4 = 768 System.out.println(a >> 2); // 192 * 4 = 48 System.out.println(-a >> 2); // -192 * 4 = -48 System.out.println(a >>> 2);// 48 System.out.println(-a >>> 2); // 很大的整数 System.out.println("-----------------------"); a = 64; System.out.println(a >>> 32); System.out.println(a << 32); System.out.println(a >> 32); System.out.println(a >> 33); System.out.println(a >> -31); } } /* 192: 0000 0000 0000 0000 0000 0000 1100 0000 << 2 0000 0000 0000 0000 0000 0011 0000 0000 192: 0000 0000 0000 0000 0000 0000 1100 0000 >> 2 0000 0000 0000 0000 0000 0000 0011 0000 -192: 1111 1111 1111 1111 1111 1111 0100 0000 >> 2 1111 1111 1111 1111 1111 1111 1101 0000 192: 0000 0000 0000 0000 0000 0000 1100 0000 >>> 2 0000 0000 0000 0000 0000 0000 0011 0000 -192: 1111 1111 1111 1111 1111 1111 0100 0000 >>> 2 0011 1111 1111 1111 1111 1111 1101 0000 */