zoukankan      html  css  js  c++  java
  • Java中的位运算

    Java的位运算(bitwise operators)直接对整数类型的位进行操作,这些整数类型包括longintshortchar byte,位运算符具体如下表:

    运算符

    说明

    <<

    左移位,在低位处补0

    >>

    右移位,若为正数则高位补0,若为负数则高位补1

    >>>

    无符号右移位,无论正负都在高位补0

    &

    与(AND),对两个整型操作数中对应位执行布尔代数,两个位都为1时输出1,否则0。

    |

    或(OR),对两个整型操作数中对应位执行布尔代数,两个位都为0时输出0,否则1。

    ~

    非(NOT),一元运算符。

    ^

    异或(XOR),对两个整型操作数中对应位执行布尔代数,两个位相等0,不等1。

    <<=

    左移位赋值。

    >>=

    右移位赋值。

    >>>=

    无符号右移位赋值。

    &=

    按位与赋值。

    |=

    按位或赋值。

    ^=

    按位异或赋值。

    左移位(<<)

    程序:

    public class LeftMoving{

        public static void main(String[] args){

               System.out.println("5<<3="+(5<<3));

        }

    }

    输出结果:

    5<<3=40

    计算过程:

    0000 0000 0000 0000 0000 0000 0000 0101         ? 5

    0000 0000 0000 0000 0000 0000 0010 1000         ? 40

    右移位(>>)

    正数

    程序:

    public class PlusRightMoving{

        public static void main(String[] args){

               System.out.println("5>>1="+(5>>1));

        }

    }

    输出结果:

    5>>1=2

    计算过程:

    0000 0000 0000 0000 0000 0000 0000 0101         ? 5

    0000 0000 0000 0000 0000 0000 0000 0010         ? 2

    负数

    程序:

    public class NegativeRightMoving{

        public static void main(String[] args){

               System.out.println("-5>>1="+(-5>>1));

        }

    }

    输出结果:

    -5>>1=-3

    计算过程:

    1111 1111 1111 1111 1111 1111 1111 1011         ? -5

    1111 1111 1111 1111 1111 1111 1111 1101         ? -3

    无符号右移位(>>>)

    程序:

    public class UnsignedRightMoving{

        public static void main(String[] args){

    System.out.println("-5>>>1="+(-5>>>1));

        }

    }

    输出结果:

    -5>>>1=2147483645

    计算过程:

    1111 1111 1111 1111 1111 1111 1111 1011         ? -5

           0111 1111 1111 1111 1111 1111 1111 1101          ? 2147483645
     

    首先复习一下Java中的基本数据类型的相关知识。

    数据类型

    大小

    最小值

    最大值

    boolean

         

    byte

    8-bit

    -128

    +127

    char

    16-bit

    Unicode 0

    Unicode 216-1

    short

    16-bit

    -215

    +215-1

    int

    32-bit

    -231

    +231-1

    float

    32-bit

    IEEE754

    IEEE754

    long

    64-bit

    -263

    263-1

    double

    64-bit

    IEEE754

    IEEE754

    void

         

    这里包括了floatdouble两个浮点型,在本文中对其不予考虑,因为位运算是针对整型的。进行位操作时,除long型外,其他类型会自动转成int型,转换之后,可接受右操作数长度为32。进行位运算时,总是先将短整型和字节型值转换成整型值再进行移位操作的。

    程序:

    1. public class ByteLeftMoving{  
    2.   
    3. public static void main(String[] args){  
    4.   
    5.     byte b = 127;  
    6.   
    7.            System.out.println("b<<3="+(b<<3));  
    8.   
    9.         System.out.println("(byte)(b<<3)="+(byte)(b<<3));  
    10.   
    11.     }  
    12.   
    13. }  


     

    输出结果:

    b<<3=1016

    (byte)(b<<3)=-8

    程序:

     

    1. public class CharLeftMoving{  
    2.   
    3. public static void main(String[] args){  
    4.   
    5.         char c = 'l';  
    6.   
    7.            System.out.println("c<<3="+(c<<3));  
    8.   
    9.         System.out.println("(char)(c<<3)="+(char)(c<<3));  
    10.   
    11.     }  
    12.   
    13. }  


    输出结果:

    c<<3=864

    (char)(c<<3)=?

    以上两个例子全部编译通过,由此可以看出,当bytechar进行移位运算时不会发生错误,并且均按照整型进行计算,当计算结果超出byte或是char所能表示的范围时则进行相应的转换(分别输出了结果-8?)。


    位运算中的操作数

    在进行移位运算时要注意整型和长整型在内存中的位数(整型是32位,长整型是64位),如果移位操作数超出了该位数则取模计算,例如:int型数据是32位的,如果左移35位是什么结果?

    程序:

    1. public class LeftMoving{  
    2.   
    3.     public static void main(String[] args){  
    4.   
    5.            System.out.println("5<<35="+(5<<35));  
    6.   
    7.     }  
    8.   
    9. }  


     

    输出结果:

    5<<35=40 

    该结果与5<<3完全相同。

    无论正数、负数,它们的右移、左移、无符号右移 32位都是其本身,比如 -5<<32=-5-5>>32=-5-5>>>32=-5

    一个有趣的现象是,把 1 左移 31 位再右移 31位,其结果为 -1

    计算过程如下:

    0000 0000 0000 0000 0000 0000 0000 0001

    1000 0000 0000 0000 0000 0000 0000 0000

    1111 1111 1111 1111 1111 1111 1111 1111

    位运算要求操作数为整数,操作数不能是字符串也不能是小数。

    如下列程序:

    1. public class BitMath{  
    2.   
    3.     public static void main(String[] args){  
    4.   
    5.         String s = "Hello";  
    6.   
    7.         long l = 99;  
    8.   
    9.         double d = 1.11;  
    10.   
    11.         int i = 1;  
    12.   
    13.         int j = 0;  
    14.   
    15.   
    16.         System.out.println("j<<s="+j<<s);    //编译错误语句  
    17.   
    18.         System.out.println("j<<d="+j<<d);    //编译错误语句  
    19.   
    20.         System.out.println("i<<j="+i<<j);    //编译可以通过  
    21.   
    22.         System.out.println("i<<l="+i<<l);    //编译可以通过  
    23.   
    24.     }  
    25.   
    26. }  


     

    由于位运算是二进制运算,不要与一些八进制数搞混,java中二进制数没有具体的表示方法。

    public class BitMath{

        public static void main(String[] args){

            System.out.println("010|4="+(010|4));

        }

    }

    输出结果:

    010|4=12

    计算过程:

    0000 0000 0000 0000 0000 0000 0000 1000   ?8

    0000 0000 0000 0000 0000 0000 0000 0100   ?4

    进行“或”计算结果为:

    0000 0000 0000 0000 0000 0000 0000 1100   ?12

    当位运算中遇见负数,必须把它转成补码(不知道什么是补码的补习功课去)再进行计算,而不是使用原码。

    程序:

    public class BitMath{

        public static void main(String[] args){

            try {

                int x = -7;

                System.out.println("x>>1="+(x>>1));

    } catch(Exception e) {

                System.out.println("Exception");

            }

        }

    }

    输出结果:

    x>>1=-4

    计算过程:

    1111 1111 1111 1111 1111 1111 1111 1001   ?-7

    1111 1111 1111 1111 1111 1111 1111 1100   ?-4

    1. public class BitMath{  
    2.   
    3.     public static void main(String[] args){  
    4.   
    5.         int i = 1;  
    6.   
    7.         int j = -1;  
    8.   
    9.         System.out.println("1>>>31="+(i>>>31));  
    10.   
    11.         System.out.println("-1>>31="+(j>>31));  
    12.   
    13.     }  
    14.   
    15. }  


     

    输出结果:

    1>>>31=0

    -1>>31=-1

    程序:

    1. public class BitMath{  
    2.   
    3.     public static void main(String[] args){  
    4.   
    5.         int a = 1;  
    6.   
    7.        a <<= 31;  
    8.   
    9.         a >>= 31;  
    10.   
    11.         a >>= 1;          
    12.   
    13.         System.out.println("a="+a);  
    14.   
    15.   
    16.         int b = 1;   
    17.   
    18.         b <<= 31;  
    19.   
    20.         b >>= 31;  
    21.   
    22.         System.out.println("b="+b);  
    23.   
    24.   
    25.         int c = 1;  
    26.   
    27.         c >>= 31;  
    28.   
    29.         c <<= 31;  
    30.   
    31.         System.out.println("c="+c);   
    32.   
    33.     }  
    34.   
    35. }  

    输出结果:

    a=-1

    b=-1

    c=0

    计算过程:

    0000 0000 0000 0000 0000 0000 0000 0001   ?a=1

    1000 0000 0000 0000 0000 0000 0000 0000   ?a=a<<31后,这里被当作是负数

    1111 1111 1111 1111 1111 1111 1111 1111   ?a=a>>31后,结果为-1

    1111 1111 1111 1111 1111 1111 1111 1111   ?a=a>>1后,结果仍为-1

    0000 0000 0000 0000 0000 0000 0000 0001   ?c=1

    0000 0000 0000 0000 0000 0000 0000 0000   ?c=c>>31后为0

    0000 0000 0000 0000 0000 0000 0000 0000   ?0左移31位仍为0

  • 相关阅读:
    How to function call using 'this' inside forEach loop
    jquery.validate.unobtrusive not working with dynamic injected elements
    Difference between jQuery.extend and jQuery.fn.extend?
    Methods, Computed, and Watchers in Vue.js
    Caution using watchers for objects in Vue
    How to Watch Deep Data Structures in Vue (Arrays and Objects)
    Page: DOMContentLoaded, load, beforeunload, unload
    linux bridge
    linux bridge
    EVE-NG网卡桥接
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/5865456.html
Copyright © 2011-2022 走看看