zoukankan      html  css  js  c++  java
  • 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
    */
  • 相关阅读:
    将现有MySQL数据库改为大小写不敏感
    在Windows中玩转Docker Toolbox
    使用ABP EntityFramework连接MySQL数据库
    数据库设计范式2——BC范式和第四范式
    让OData和NHibernate结合进行动态查询
    文档在线预览的实现
    有哪些老鸟程序员知道而新手不知道的小技巧?自我感受
    EEPROM的概念接口类型及软件实例
    flash的几种模式Normal Mode、DUAL Mode、Quad Mode的概念和区别
    ESP8266 打造一款物联网产品---搭建环境编译及烧录
  • 原文地址:https://www.cnblogs.com/zhaoyuan72/p/11082522.html
Copyright © 2011-2022 走看看