Java中关于位运算的面试题

Wesley13
• 阅读 716

位运算的效率是最高的,因为位位运算是直接对二进制进行操作

位运算只能应用于整型和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
*/
点赞
收藏
评论区
推荐文章
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
java 二进制(原码 反码 补码),位运算,移位运算,约瑟夫问题
一.二进制,位运算,移位运算1.二进制对于原码,反码,补码而言,需要注意以下几点:(1).Java中没有无符号数,换言之,Java中的数都是有符号的;(2).二进制的最高位是符号位,0表示正数,1表示负数;(3).正数的原码,反码,补码都一样;(4).负数的反码它的原码符号位不变,其他位取反;(5).
Wesley13 Wesley13
3年前
java中的7个位运算运算符
位运算指的是针对整数的二进制进行的位移操作。位运算提供比算术运算更高的效率,但是位运算的代码可读性较差,建议所有使用位运算的地方写上注释。Java中提供7个位运算符用于位运算。左移(<<)左移运算是将操作数二进制值逐位左移若干位,左移过程中符号位不变,高位溢出则舍弃,低位则补0。范例结果范例结果00000001<<
Wesley13 Wesley13
3年前
java位运算大全
位运算因为是CPU直接支持的操作指令,也是基于二进制的操作,所以具有相当高的效率,在一些场合,合理应用位运算将具有很高的性能。通常在一些加密算法,图型算法中都会使用到位运算。Java位运算符位 运 算 符 用 来 对 二 进制 位 进 行 操 作 ,Java中提 供 了 如 下所 示 的 位 运 算符:位 运 算 符 (>>,<<
Wesley13 Wesley13
3年前
OC中的位运算
转载:https://www.jianshu.com/p/b868b30c0c88OC中的位运算和C/C语言的位运算是一样的。一般有&(按位与),|(按位或),~(按位取反),<<(左移),(右移),^(异或)以及&(按位与然后赋值),|(按位或然后赋值)等对枚举类型的操作中常常会见到。例如定义一个季节SeasonT
Wesley13 Wesley13
3年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Wesley13 Wesley13
3年前
Java中的位运算及简单的算法应用介绍
\TOC\Java中的位运算及简单的算法应用介绍众所周知,计算机底层是二进制。而java作为一门计算机编程语言,也对二进制的位运算提供了完整的支持。在java中,int是32位的,也就是说可以用来实现32位的位运算。方便起见,我们一般用16进制对它赋值,比如:0011表示成16进制是0x3,110111表示成16进制是0x37。
Stella981 Stella981
3年前
20180109Java位运算
一,Java位运算1.表示方法:  在Java语言中,二进制数使用补码表示,最高位为符号位,正数的符号位为0,负数为1。补码的表示需要满足如下要求。 (1)正数的最高位为0,其余各位代表数值本身(二进制数)。 (2)对于负数,通过对该数绝对值的补码按位取反,再对整个数加1。 2.位运算符位运算表达式由
可莉 可莉
3年前
20180109Java位运算
一,Java位运算1.表示方法:  在Java语言中,二进制数使用补码表示,最高位为符号位,正数的符号位为0,负数为1。补码的表示需要满足如下要求。 (1)正数的最高位为0,其余各位代表数值本身(二进制数)。 (2)对于负数,通过对该数绝对值的补码按位取反,再对整个数加1。 2.位运算符位运算表达式由
Wesley13 Wesley13
3年前
C#位运算
在C中可以对整型运算对象按位进行逻辑运算,按位进行逻辑运算的意义是:依次取被运算对象的每个位,进行逻辑运算,每个位的逻辑运算结果是结果值的每个位,C支持的位逻辑运算符如下表。!(https://oscimg.oschina.net/oscnet/e3ff3ca0d8190d7cf6a5c8269feaab32004.jpg)1、位逻辑非运算