Java位运算经典实例
一 源码、反码、补码
正数的源码、反码、补码相同,例如5:
5的源码:101
5的反码:101
5的补码:101
负数的源码、反码、补码不同,例如-5:
-5的源码:10000101
-5的反码:111111010 (取反操作)
-5的补码:111111011 (补码加1操作)
计算机所有数据都以补码存储和运算。
二 位操作
位操作包含&,|,!分别表示与,或非。
eg:
5 & 4 = 101 & 100 = 100(按位取“与”,1 & 1 = 1,0 & 1 = 0)
5 | 4 = 101 | 100 = 101 (按位取“或”,1 | 0 = 1, 0 | 0 = 0)
!5 = ! 101 = 010 (按位取“反”,!1 = 0, !0 = 1)
三 位运算实例
eg:给定一个有符号整数X(32位),写一个方法,检查这个数是否是4的N次方,N是非负整数。
下面是用Java解答这道题:
public class Test {
public static void main(String[] args) {
for(int i = -64; i < 400; i+=1) {
if(isPowerOfFour5(i))
System.out.println("test "+ i + " is power of four!");
}
}public static boolean isPowerOfFour1(int x) {
if(x == 0) return false;
while ((x % 4) == 0) {
x /= 4;
}
return x == 1;
}
public static boolean isPowerOfFour2(int x) {
if(x == 0) return false;
while ((x % 4) == 0) {
x >>= 2;
}
return x == 1;
}
public static boolean isPowerOfFour3(int x) {
double n = Math.log(x) / Math.log(4);
if(n -(int)n != 0) return false;
return n >= 0;
}
public static boolean isPowerOfFour4(int x) {
if(x == 0) return false;
int y = (int) Math.sqrt(x);
if(y * y == x)
return ((y & (y-1)) == 0);
return false;
}
public static boolean isPowerOfFour5(int x) {
if(x == 0) return false;
return (x & (x - 1)) == 0 && (x & 0xAAAAAAAA) == 0;
}
}
稍微解释一下,第一个方法的算法复杂度是log4X,原理是,凡是4的N次方的数(N是大于等于0的正整数),则对X一直取余,最终结果肯定等于1,比如4 * 4 * 4 = 64。
第二个方法和第一个方法原理一样,>>2相当于/4。
第三个方法利用公式:4N = X => N = log4X = logX / log4,所以只需要判断N大于等于0且为整数即可(如果n-(int)n != 0表明n不是整数)。
第四个方法的原理如下:
40 41 42 43 … 4n
(22)0 (22)1 (22)2 (22)3 … (22)n
则y = Math.sqrt(x)等于:
20 21 22 23 … 2n
所以我们只需要判断y是整数,且y是2的n次方,n大于等于0且为整数:
判断一个整数y是不是2的n次方,只需要判断y&(y-1)等不等于0即可。
第五种方法的原理如下:
40 1
41 100
42 10000
43 1000000
…
4n 100000000…
可以发现,所有以4为底的N次方的数的2进制都只有1位为1,且为1的这一位在奇数位上。
因此,我们首先判断X的2进制只有一位,且该位不在偶数位上,还要注意0必须除外,因为0&任何数都等于0。
前面说过,x & (x - 1) == 0则表明x是2的n次方,我们应该知道任何2进制只有一位为1的数都可以表示为2的n次方。
既然已经确定x的2进制数只有一位为1,那么(x & 0xAAAAAAAA) == 0表明为1的这一位在奇数位上,因为0xAAAAAAAA = 1010 1010 1010 1010
Java位运算经典实例的更多相关文章
- Java位运算总结:位运算用途广泛《转》
前天几天研究了下JDK的Collection接口,本来准备接着研究Map接口,可是一查看HashMap类源码傻眼咯,到处是位运算实现,所以我觉得还是有必要先补补位运算知识,不然代码看起来有点费力.今天 ...
- Java位运算总结:位运算用途广泛
前天几天研究了下JDK的Collection接口,本来准备接着研究Map接口,可是一查看HashMap类源码傻眼咯,到处是位运算实现,所以我觉得还是有必要先补补位运算知识,不然代码看起来有点费力.今天 ...
- Java 位运算超全面总结
1.原码.反码.补码 关于原码.反码.补码的相关知识作者不打算在这里长篇大论,相关知识已有别的大佬总结很好了,还请老铁自行 Google,不过有篇知乎回答是作者学编程以来见过对相关知识最通俗易懂,生动 ...
- Java 位运算2-LeetCode 201 Bitwise AND of Numbers Range
在Java位运算总结-leetcode题目博文中总结了Java提供的按位运算操作符,今天又碰到LeetCode中一道按位操作的题目 Given a range [m, n] where 0 <= ...
- 【位运算经典应用】 N皇后问题
说到位运算的经典应用,不得不说N皇后问题. 学过程序设计的都知道N皇后问题,没听过也没关系.很简单,最传统的的N皇后问题是这个样子的,给你一个n * n大小的board,让你放n个皇后(国际象棋),要 ...
- Java位运算原理及使用讲解
前言日常开发中位运算不是很常用,但是巧妙的使用位运算可以大量减少运行开销,优化算法.举个例子,翻转操作比较常见,比如初始值为1,操作一次变为0,再操作一次变为1.可能的做法是使用三木运算符,判断原始值 ...
- (转)java位运算
转自:http://aijuans.iteye.com/blog/1850655 Java 位运算(移位.位与.或.异或.非) public class Test { public static ...
- 我们必须要了解的Java位运算(不仅限于Java)
本文原创地址为 https://www.cnblogs.com/zh94/p/16195373.html 原创声明:作者:陈咬金. 博客地址:https://www.cnblogs.com/zh94/ ...
- java位运算(操作)的使用
位操作是程序设计中对位模式按位或二进制数的一元和二元操作. 在许多古老的微处理器上, 位运算比加减运算略快, 通常位运算比乘除法运算要快很多. 在现代架构中, 情况并非如此:位运算的运算速度通常与加法 ...
随机推荐
- mysqlbinlog 导出日志
1.找到日志所在的位置 ls 正好我需要的日志在000011这个二进制文件里,所以直接执行下面的语句: mysqlbinlog --no-defaults --start-datetime=" ...
- 分析案例:界面提示“基础链接已经关闭:接收时发生错误”----本质为StackOverflow
问题描述: 一个业务复杂.执行时间很长的功能,经常报出“基础链接已经关闭:接收时发生错误”,很是蹊跷... 问题分析: 首先,查阅应用服务器的系统日志,发现问题发生时总是会伴随着w3wp进程崩溃的错误 ...
- Apache Tomcat 7 安装与配置
下载 首先需要下载tomcat7的安装文件,地址如下: http://mirror.bit.edu.cn/apache/tomcat/tomcat-7/v7.0.69/bin/apache-tomca ...
- ife-task0003学习收获总结
+ 编写可维护的css原则是,尽量减少改动时要编辑的地方(减少代码重复). + CSS布局奇淫技巧之-高度自适应 高度自适应:通过绝对定位来解决高度自适应的问题,元素不设置高度,设置绝对定位,将top ...
- 【Telnet】使用Telnet协议连接到远程Shell执行脚本
介绍 本文介绍如何通过Telnet协议连接到远程Shell,执行脚本,并获取执行结果: 相关文章: <[Jsch]使用SSH协议连接到远程Shell执行脚本>http://www.cnbl ...
- Mysql 客户端查询结果如何保存到本地而不是服务端?
应用场景:知道某台DB服务器的IP和账户,登录上去查询了10W条记录,需要把这些记录拉到本地做分析 方法1,远程连接到DB服务器执行OUTFILE命令,文件存储在DB机器上,只有mysql账户的情况下 ...
- sqlserver无ldf日志文件附加的方法(数据库没有完全关闭,无法重新生成日志)
数据库的ldf日志文件被删了,直接附加时报错:数据库没有完全关闭,无法重新生成日志 那怎么恢复数据呢?方法如下: 在数据库中新建一个同名的数据库(文件路径要与原来的相同,ldf的文件名也要相同),然后 ...
- 线程让出实验【RT-Thread学习笔记 4】
API: rt_thread_yield 线程函数中调用,本线程释放MCU.如果此时有别的相同优先级的任务整处于等待状态,将获得MCU使用权. 线程让出就是给OS增加一个任务调度的机会. 创建两个线程 ...
- delphi中webbrowser的用法
WebBrowser1.GoHome; //到浏览器默认主页 WebBrowser1.Refresh; //刷新 WebBrowser1.GoBack; //后退 WebBrowser1.GoForw ...
- Emacs使用projectile-rails 插件注意事项
插件地址 https://github.com/asok/projectile-rails 我自己使用rbenv这个ruby版本控制工具来,管理下载ruby,但是他不是全局安装ruby之类的gem,如 ...