关闭

浅谈java中的位运算

287人阅读 评论(1) 收藏 举报
分类:

众所周知,计算机中的所有数据都是以二进制形式存储的,位运算直接作用在内存中的二进制数据,所以运算速度非常快。

首先明白一点,位运算只能用于整型数据,int 类型占4个字节,1个字节占8位,其次,要清楚6种位运算符:

&:与,只有1&1=1,其余都为0;

 | :或,只有0|0=0,其余都为1;

^ :异或,两个为相同为0,相异为1;

~:取反,各位0变1,1变0;

<<:左移,各二进制位全部左移若干位,高位丢弃,低位补0;

>>:右移,各二进制位全部右移若干位,对无符号数,高位补0,低位移除,对有符号数,java是算数右移,即高位补符号位,符号位:0正数,1负数

在计算机中负数是以其正值的补码形式存储的。

原码:对整型数直接转化为二进制数,最高位为符号位

反码:正数的反码与其原码相同;负数的反码是除符号位外对其原码逐位取反。

补码:正数的补码与其原码相同;负数的补码是在其反码的末位加1。

着重分析一下左移和右移,如下:

int i=15;//15=8+4+2+1,即 00000000 00000000 00000000 00001111
int j=-15;//11111111 11111111 11111111 11110001,负数存的是补码,
System.out.println(i<<2);// 00000000 00000000 00000000 00111100=60
System.out.println(j<<2);//11111111 11111111 11111111 11000100注意这是补码,
		        //输出的时候还要转换为原码,除符号位外逐位取反+1
		       //10000000 00000000 00000000 00111100=-60
System.out.println(i>>2);//00000000 00000000 00000000 00000011=3
System.out.println(j>>2);//11111111 11111111 11111111 11111100注意这是补码,除符号位外逐位取反+1
		         //10000000 00000000 00000000 00000100=-4

常见的利用位运算进行的操作:

1)《剑指Offer》中给出过这样一道题:写一个函数求两个整数之和,要求在函数体内不能用算数运算符加、减、乘、除。

思路:对于十进制数相加我们其实做了三步:

   (1) sum=各位相加不进位;

   (2)carry=做进位,取出进位数

   (3)result=sum+carry;

对于二进制数求和同样适用,所以函数如下:

public static int AddWithoutArithmetic(int num1, int num2)
	{
		//什么时候退出递归呢?当两数相加没有发生进位的时候
		if(num2==0){
			return num1;
		}
		//各位相加不进位,0+0=0 1+1=0;0+1=1 1+0=1 和位运算符异或(^)相同
		int sum=num1^num2;
		//做进位,取出进位值
		int carry=(num1&num2)<<1;//只有1+1才会发生进位,和运算符与(&)相同,并且二进制中的进位相当于左移一位
		return AddWithoutArithmetic(sum,carry);
	}

2)判断奇偶数

public static String OddOrEven(int n){
		if((n&1)==0){//n=4,00000000 00000000 00000000 00000100&00000000 00000000 00000000 00000001=00000000 00000000 00000000 00000000
			return "even";
		}else{//n=5;101&001=001
			return "odd";
		}	
	}
3)交换两数

public static void exchange(int a,int b){
		a^=b;//a=a^b
		b^=a;//b=b^a=b^(a^b)=(b^b)^a=0^a=a
		a^=b;//a=a^b=(a^b)^(a)=(a^a)^b=0^b=b
	}
4)变换正负号(取反+1)

System.out.println(~7+1);
		//00000000 00000000 00000000 00000111=7
	    //11111111 11111111 11111111 11111000=~7
		//11111111 11111111 11111111 11111001这是补码,转换为整数时,需要除符号为外逐位取反,再加1
		//10000000 00000000 00000000 00000111=-7
5)求绝对值

 public static int abs(int a){
		int i=a>>31;//取符号位
		return i==0?a:(~a+1);//或者return (a^i)-i;因为a^0=a;a^(-1)=~a;这种方式没用任何判断表达式包括三目表达式
	 }



1
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

浅谈java及应用

给初学者之一:浅谈java及应用   学java不知不觉也已经三年了, 从不知java为何物到现在一个小小的j2ee项目经理,虽说不上此道高手,大概也算有点斤两了吧。每次上网,泡bbs逛论坛,没少去java相关的版面,总体感觉初学者多,高手少,精通的更少   由于我国高等教育制度教材陈旧,加上j...
  • u012402926
  • u012402926
  • 2016-05-04 17:54
  • 143

浅谈java(一)

一.java的历史和发展前景       java从产生到现在已经有20多年的历史了。自其出现以来就以惊人的速度发展,使用java开发的人数不胜数。       Java 语 言 有 着 广 泛 的 应 用 前 景 ,大 体 上 可 以...
  • windy_03271
  • windy_03271
  • 2013-03-27 17:45
  • 342

浅谈Java并发编程

浅谈Java并发编程(一)作为一个工作经验还不是很足的小程序员,第一次写博客,不足之处还希望业内前辈多多指点。以前接触并发编程的机会还是挺少的,但是进入了一个大平台,用户量很可观,所以在程序处理是并发的情况很常见,所以觉得好好了解这方面的知识很有必要,言归正传,接下来我将从一下几点浅谈Java并发编...
  • missY_H
  • missY_H
  • 2017-05-01 23:03
  • 160

浅谈C语言与JAVA语言

C语言是我第一门编程语言。java是我的第二门编程语言。
  • java_M_du
  • java_M_du
  • 2017-06-19 00:45
  • 163

红黑树深入剖析及Java实现

红黑树深入剖析及Java实现 红黑树是平衡二叉查找树的一种。为了深入理解红黑树,我们需要从二叉查找树开始讲起。 BST 二叉查找树(Binary Search Tree,简称BST)是一棵二叉树,它的左子节点的值比父节点的值要小,右节点的值要比父节点的值大。它的高度决定...
  • u014352080
  • u014352080
  • 2016-12-09 09:00
  • 2434

浅谈人工智能

历史      各个文明中都有杰出的工匠发明了自动机器来代替人类劳动,早在春秋时期鲁班就发明了世界上第一个机器人,可在空中飞翔‘三日不下’;三国时期蜀汉的诸葛亮发明了‘木牛流马’来运送战备物资,称得上是最早的军用机器人;古希腊人希罗发明了世界上第一部蒸汽机......可...
  • oba_gaga
  • oba_gaga
  • 2016-10-09 20:57
  • 1801

浅谈数据库设计

浅谈数据库设计 ——-目录(?)[+]第一章 需求分析设计简介设计步骤需求分析重要性实例小型电子商务网站第二章 逻辑设计E-R图设计范式概要第一范式1NF第二范式2NF第三范式3NF BC范式第三章 物理设计物理设计要做什么选择哪种数据库mysql常用的存储引擎表及字段的命名规范字段类型选...
  • CCSUXWZ
  • CCSUXWZ
  • 2017-06-21 17:50
  • 295

浅谈JVM及原理

1、什么是JVM ? JVM, 中文名是Java虚拟机, 正如它的名字, 是一个虚拟机器,来模拟通用的物理机。 JVM是一个标准,一套规范,  规定了.class文件在其内部运行的相关标准和规范。 及其相关的内部构成。 比如:所有的JVM都是基于栈结构的运行方式。那么不符合这种要求的,不...
  • weiguolong0306
  • weiguolong0306
  • 2017-03-04 15:54
  • 2463

浅谈面向对象

这段时间天天被米老师洗脑式的上课,讲的都是一个中心,面向对象!     但是,面向对象到底是怎么回事儿呢?我们看一下维基百科里是怎么说的:     面向对象程序设计(英语:Object-oriented programming,缩写:OOP)是一种程序设计范型...
  • laner0515
  • laner0515
  • 2014-06-29 15:33
  • 3254

浅谈Java并发编程系列(六) —— 线程池的使用

线程池的作用 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的资源浪费。 提高响应速度。当任务到达时,不需要等到线程创建就能立即执行。 方便管理线程。线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以对线程进行统一的分配,优化及监控。 设置线程池...
  • codershamo
  • codershamo
  • 2016-07-11 21:13
  • 1023
    个人资料
    • 访问:14125次
    • 积分:422
    • 等级:
    • 排名:千里之外
    • 原创:26篇
    • 转载:9篇
    • 译文:0篇
    • 评论:7条