java中位运算详解

位运算

什么是位操作?

程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算就是直接对整数在内存中的二进制位进行操作。比如,and运算本来是一个逻辑运算符,但整数与整数之间也可以进行and运算。举个例子,6的二进制是110,11的二进制是1011,那么6 and 11的结果就是2,它是二进制对应位进行逻辑运算的结果(0表示False,1表示True,空位都当0处理)。

算术运算简称运算。指按照规定的法则和顺序对式题或算式进行运算,并求出结果的过程。包括:加法、减法、乘法、除法、乘方、开方等几种运算形式。

例如,查看算术和位操作方法在查找RGB值的绿色部分时的区别:

  • 算术操作:
(rgb / 256) % 256
  • 位运算:
(rgb >> 8) & 0xFF

虽然两者都做相同的事情,但第二种方法的速度要快得多,因为它直接在内存中工作,而不是通过抽象级别。
我们将在本文后面探讨每个操作符的作用(>>和&)。

位运算操作

按位操作采用一个或多个位模式或二进制数字,并在位级别对它们进行操作。它们本质上是我们用来操纵bit的工具,位运算符直接操作bit数据。

位运算优势

  1. 它们是快速而简单的动作。

  2. 它们由处理器直接支持。

  3. 它们用于操纵用于比较和计算的值。

  4. 位运算非常简单,比算术运算快得多。

让我们快速了解一下每种主要的位运算符及其用法。

& 操作符(与)

AND(&)是一个二进制运算符,用于比较两个长度相等的操作数。操作数从可读形式转换为二进制表示形式。对于每个位,该操作检查两个操作数中的两个位是否都是1。如果是,则该位在答案中设置为1。否则,相应的结果位设置为0。

它本质上是将每个位乘以另一个操作数中的相应位。因为将任何值乘以0得到0,与任何0位的AND比较将得到0。

如果两个输入位为1,则输出为1。

  • 1&1 = 1。

在所有其他情况下,其值为0,例如:

  • 1&0 = 0。

  • 0&1 = 0。

  • 0&0 = 0。

    0101 (decimal 5)
AND 0011 (decimal 3)

0∗0=0
1 * 0 = 0
0 * 1 = 0 1∗1=1

因此可以计算出值为

0001 

java代码;

class AndOperation {
    public static void main( String args[] ) {
        int x = 12;
        int y = 10;
        System.out.println("位运算操作 (" + x + " , " + y + ") is: " + (x & y)); // yields to 8
    }
}

|操作符(或)

OR运算符(|)是一个二进制运算符,它接受两个等长的操作数,但将它们与AND进行相反的比较;如果相应的位为1,则答案为1。否则,答案为0。换句话说,如果给定的输入之一为1,则按位OR返回“1”。

如果两个输入位为0,则输出为0。

  • 0 | 0 = 0。
    在所有其他情况下,它是1。例如:

  • 1 | 0 = 1。

  • 0 | 1 = 1。

  • 1 | 1 = 1。

a = 12
b = 10
---------------------------------
a 二进制 : 0000 0000 0000 1100
b 二进制 : 0000 0000 0000 1010
---------------------------------
a | b   : 0000 0000 0000 1110
---------------------------------

java代码;

class OROperation {
    private static int helper(int x, int y) {
        return x | y;
    }
    public static void main(String[] args) {
        int x = 12;
        int y = 10;
        System.out.println("位运算操作 " + x + ", " + y + " is: " + helper(x, y)); // yields to 14
    }
}

~ 操作符(取反)

NOT(~)或有时称为位补码运算符,是一种一元运算,它接受单个输入,并将二进制表示中的每一位换成相反的值。

0的所有实例都变为1,1的所有实例都变为0。换句话说,不反转每个输入位。这个倒序被称为位序列的一的补码。

例如,考虑x=1。

x的二进制数表示为:

x=00000000 00000000 00000000 00000001

现在,~x是:

x=11111111 11111111 11111111 11111110

这使得数字为负数,因为任何以1开头的位集合都是负数。

java代码;

class NOTOperation {
    public static void main( String args[] ) {
        int a = 1;
        System.out.println("位运算操作  : " + ~a);
    }
}

^ 操作符(异或)

按位异或运算(^)是“异或”的缩写,是一个二进制运算符,它接受两个输入参数并比较每个对应的位。如果位是相反的,则结果在该位等于1。如果一样则返回0。

  • 1^1 = 0。

  • 0^0 = 0。

  • 1^0 = 1。

  • 0^1 = 1。

例如:

a = 12
b = 10
---------------------------------
a 二进制 : 0000 0000 0000 1100
b 二进制 : 0000 0000 0000 1010
---------------------------------
a ^ b   : 0000 0000 0000 0110
---------------------------------

java代码:

class XOROperation {
    public static void main( String args[] ) {
        int x = 12;
        int y = 10;
        System.out.println("位运算操作 (x , y) is : " + (x ^ y)); // yields to 6
    }
}

左右位移操作符号(>> << >>> <<<)

位移位是一种按位操作,其中移动一系列位的顺序以有效地执行数学运算。位移位将数字二进制表示形式中的每个数字向左或向右移动第二个操作数指定的空格数。

这些运算符可以应用于整数类型,如int、long、short、byte或char。

  • 左移位:<<是左移位运算符,满足逻辑和算术移位的需要。

  • 算术/有符号右移:>>是算术(或有符号)右移运算符。

  • 逻辑/无符号右移:>>>是逻辑(或无符号)右移运算符。

在Java中,所有整数数据类型都是有符号的,<<和>>仅仅是算术移位。

下面是一个左移的例子:

6 = 00000000 00000000 00000000 00000110

将该位模式向左移动一个位置(6<<1)得到数字12:

6<<1 = 00000000 00000000 00000000 00001100

<<数字向左移动了一个位置,右边的最后一个数字填充了零。注意,左移相当于2的幂的乘法。同理>>相当于去除最后一个bit位置,然后第一个bit补0。

java代码:

class LeftShift {
    private static int helper(int number, int i) {
        return number << i;// multiplies `number` with 2^i times.
    }
    public static void main(String[] args) {
        int number = 100;
        System.out.println(number + " shifted 1 position left, yields to " + helper(number, 1));
        System.out.println(number + " shifted 2 positions left, yields to " + helper(number, 2));
        System.out.println(number + " shifted 3 positions left, yields to " + helper(number, 3));
        System.out.println(number + " shifted 4 positions left, yields to " + helper(number, 4));
    }
}

位运算技巧

现在,让我们看看使用位运算符可以实现的一些技巧。

检查数字是否为偶数

这一个测试你的知识如何和工作,以及如何奇偶数不同的二进制数。您可以简单地使用:

(x & 1 ) == 0

任何时候,奇数最后一位bit为1,1的二进制为 0001 当x&1时候只要判断结果等于1则,x最后一个bit就是为1,此时为奇数。

将字符转换为大写或小写

这个技巧要求你有对二进制大小写字符的知识。您可以使用ch^=32将任何字符ch转换为相反的大小写。

这是因为小写字母和大写字母的二进制表示几乎相同,只有1位不同。

使用异或操作可以切换单个位并将其交换为相反的值,从而使小写字符变为大写,反之亦然。

public class Test 
{ 
      
    static int x=32; 
】
    static String toggleCase(char[] a) 
    { 
        for (int i=0; i<a.length; i++) { 
            a[i]^=32; 
        } 
        return new String(a); 
    } 
      
    public static void main(String[] args)  
    { 
        String str = "CheRrY"; 
        System.out.print("Toggle case: "); 
        str = toggleCase(str.toCharArray()); 
        System.out.println(str); 
          
        System.out.print("Original string: "); 
        str = toggleCase(str.toCharArray()); 
        System.out.println(str);     
    } 
} 

结束

识别下方二维码!回复: 入群 ,扫码加入我们交流群!

点赞是认可,在看是支持

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值