Java的位运算(bitwise operators)直接对整数类型的位进行操作,这些整数类型包括long、int、short、char和 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

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

程序:

public class ByteLeftMoving{

public static void main(String[] args){

byte b = 127;

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

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

}

}

输出结果:

b<<3=1016

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

程序:

public class CharLeftMoving{

public static void main(String[] args){

char c = 'l';

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

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

}

}

输出结果:

c<<3=864

(char)(c<<3)=?

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

位运算中的操作数

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

程序:

public class LeftMoving{

public static void main(String[] args){

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

}

}

输出结果:

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

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

如下列程序:

public class BitMath{

public static void main(String[] args){

String s = "Hello";

long l = 99;

double d = 1.11;

int i = 1;

int j = 0;

System.out.println("j<<s="+j<<s);    //编译错误语句

System.out.println("j<<d="+j<<d);    //编译错误语句

System.out.println("i<<j="+i<<j);    //编译可以通过

System.out.println("i<<l="+i<<l);    //编译可以通过

}

}

 

由于位运算是二进制运算,不要与一些八进制数搞混,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

public class BitMath{

public static void main(String[] args){

int i = 1;

int j = -1;

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

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

}

}

输出结果:

1>>>31=0

-1>>31=-1

程序:

public class BitMath{

public static void main(String[] args){

int a = 1;

a <<= 31;

a >>= 31;

a >>= 1;

System.out.println("a="+a);

int b = 1;

b <<= 31;

b >>= 31;

System.out.println("b="+b);

int c = 1;

c >>= 31;

c <<= 31;

System.out.println("c="+c);

}

}

输出结果:

a=-1

b=-1

c=0

计算过

java位运算的更多相关文章

  1. Java 位运算2-LeetCode 201 Bitwise AND of Numbers Range

    在Java位运算总结-leetcode题目博文中总结了Java提供的按位运算操作符,今天又碰到LeetCode中一道按位操作的题目 Given a range [m, n] where 0 <= ...

  2. Java位运算总结:位运算用途广泛《转》

    前天几天研究了下JDK的Collection接口,本来准备接着研究Map接口,可是一查看HashMap类源码傻眼咯,到处是位运算实现,所以我觉得还是有必要先补补位运算知识,不然代码看起来有点费力.今天 ...

  3. Java位运算原理及使用讲解

    前言日常开发中位运算不是很常用,但是巧妙的使用位运算可以大量减少运行开销,优化算法.举个例子,翻转操作比较常见,比如初始值为1,操作一次变为0,再操作一次变为1.可能的做法是使用三木运算符,判断原始值 ...

  4. (转)java位运算

    转自:http://aijuans.iteye.com/blog/1850655 Java 位运算(移位.位与.或.异或.非)   public class Test { public static ...

  5. Java位运算总结:位运算用途广泛

    前天几天研究了下JDK的Collection接口,本来准备接着研究Map接口,可是一查看HashMap类源码傻眼咯,到处是位运算实现,所以我觉得还是有必要先补补位运算知识,不然代码看起来有点费力.今天 ...

  6. Java 位运算超全面总结

    1.原码.反码.补码 关于原码.反码.补码的相关知识作者不打算在这里长篇大论,相关知识已有别的大佬总结很好了,还请老铁自行 Google,不过有篇知乎回答是作者学编程以来见过对相关知识最通俗易懂,生动 ...

  7. 我们必须要了解的Java位运算(不仅限于Java)

    本文原创地址为 https://www.cnblogs.com/zh94/p/16195373.html 原创声明:作者:陈咬金. 博客地址:https://www.cnblogs.com/zh94/ ...

  8. Java位运算经典实例

    一 源码.反码.补码 正数的源码.反码.补码相同,例如5:            5的源码:101            5的反码:101            5的补码:101 负数的源码.反码.补 ...

  9. Java 位运算(移位、位与、或、异或、非)

    Java提供的位运算符有:左移( << ).右移( >> ) .无符号右移( >>> ) .位与( & ) .位或( | ).位非( ~ ).位异或( ...

随机推荐

  1. php特殊语法--模板引擎中比较常见

    <?php $a=array(1,2,0); foreach ($a as $v): if($v>1): ?> 5 <?php endif; endforeach; ?> ...

  2. 【转】PHP error_reporting() 错误控制函数功能详解

    定义和用法: error_reporting() 设置 PHP 的报错级别并返回当前级别.   函数语法: error_reporting(report_level)   如果参数 level 未指定 ...

  3. C++资料大全

    本文内容源自GitHub<Awesome C/C++>. 关于 C++ 框架.库和资源的一些汇总列表,由 fffaraz 发起和维护. 内容包括:标准库.Web应用框架.人工智能.数据库. ...

  4. C# Tips: 将 VS2012 / VS2013 的.sln文件、project文件转换成 VS2010格式

    原来有一些VS2013的工程文件(.sln..csproj),使用.Net 4.0.现需要将它们转换成VS2010格式. 经实验,办法如下: (1) 在Solution文件(.sln)中: 把文件头部 ...

  5. lucene、lucene.NET详细使用与优化详解

    lucene.lucene.NET详细使用与优化详解 2010-02-01 13:51:11 分类: Linux 1 lucene简介1.1 什么是luceneLucene是一个全文搜索框架,而不是应 ...

  6. Android手机平板两不误,使用Fragment实现兼容手机和平板的程序

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/8744943 记得我之前参与开发过一个华为的项目,要求程序可以支持好几种终端设备,其 ...

  7. Func系列4:其他功能

    非Python API接口支持 Func通过非Python API实现远程调用,目的是为第三方工具提供调用及返回接口.Func使用func-transmit命令来实现,支持YAML.JSON格式,实现 ...

  8. Centos7安装Zabbix3.0

    1.安装服务器端包 #rpm -ivh http://repo.zabbix.com/zabbix/3.0/rhel/7/x86_64/zabbix-release-3.0-1.el7.noarch. ...

  9. Sublime text2用户自定义配置

    [{ "keys": ["ctrl+d"], "command": "run_macro_file", "ar ...

  10. ASP.NET ViewState详解

    ASP.NET ViewState详解[转载] 作者:Infinities Loop 概述 ViewState是一个被误解很深的动物了.我希望通过此文章来澄清人们对ViewState的一些错误认识.为 ...