1、在写代码的过程中,偶尔使用到了
[java] view plain copy print?
Integer.highestOneBit(i)
这个函数调用。使用的第一感觉就是这个函数是干什么用的,通过查看文档得知,这个函数的作用是取 i 这个数的二进制形式最左边的最高一位且高位后面全部补零,最后返回int型的结果。
首先来补充一点背景知识。
1、在计算机系统中,数值一律使用补码来表示和存储。主要原因是使用补码可以将符号位和其它位统一处理;同时,减法也可按照加法来处理。另 外, 两个用补码表示的数相加时,如果最高位(符号位)有进位,则进位被舍弃。
- 补码与原码的转换过程几乎相同。
- 数值的补码表示(分两种)
- 正数的补码:与原码相同
- 负数的补码:符号位位1,其余位位该数绝对值的原码按位取反;然后整个数加1
- 已知一个数的补码,求原码的操作分为两种情况
- 如果补码的符号位“0”,表示是一个正数,所以补码就是该数的原码
- 如果补码的符号位为“1”,表示是一个负数,求原码的操作可以是:符号位位1,其余各位取反,然后整个数加1。
2、移位运算符就是在二进制的基础上对数字进行平移。Java按照平移的方向和填充数字的规则分为三种:<<左移,>>带符号右移 和>>>无符号右移。
3、 在Java的移位运算中,byte、short和char类型移位后的结果会变成int类型,对于byte、short、char和int进行移位时,对于char、short、char和int进行移位操作时,规定实际移动的次数是移动次数和32的余数,也就是移位33次和移位1次得到的结果相同。移动long型的数值时,规定实际移动的次数是移动次数和64的余数,也就是移动65次移位1次得到相同的结果。
(1) << 运算规则:按二进制形式吧所有的数字向左移动对应的位数,高位移出(舍弃),低位的空位补零。
语法格式:
需要移位的数字<<移位的次数
例如:4<<2 ,则是将数字4左移2位
计算过程
4<<2
Java中一个int数占四个字节,那么4的二进制数字为00000000 00000000 00000000 00000100,然后把该数字左移两位。其它的数字都朝右平移两位,最后在低位(右侧)的两个空位补零。则得到的最终结果是00000000 00000000 00000000 00010000,即转换为十进制数16。
在数字没有溢出的前提下,对于正数和负数,左移一位都相当于乘以2的1次方,左移n位就相当于乘以2的n次方。
在溢出的前提前,则不符合这个规律。读者可以尝试输出(long)1610612736*4和1610612736<<2这两个结果进行比对。
(2)>>运算规则:按二进制形式吧所有的数字都向右移动对应的位置,低位移出(舍弃),高位的空位补符号位,即正数补零,负数补1。
语法格式:
需要移位的数字>>移位的次数
例如:-4>>2和4>>2,则是将数字 -4和4右移2位
计算过程
4>>2
Java中一个int数占四个字节,同样4的二进制为00000000 00000000 00000000 00000100,然后把该数字右移两位。其它的数字都朝左平移两位,最后在高位补符号位(该数是正数,全补零),得到的结果是00000000 00000000 00000000 00000001,即使十进制的1。数学意义就是右移移位相当于除2,右移n位相当于除以2的n次方。
4>>2
由于负数在计算机中是以补码的形式存储的,那么-4的二进制为11111111 11111111 11111111 11111100,然后把该数字右移两位,其它数字都朝左平移两位,最后在高位补符号位(该数是负数,全补一),得到的结果是11111111 11111111 11111111 11111111(补码格式),即是十进制的-1。
(3)>>>运算规则:按二进制形式吧所有的数字向右移动对应的位数,低位移出(舍弃),高位的空位补零。正数运算结果与带符号右移相同,对于负数来说则不同。
对于4>>>2和-4>>>2运算,可以通过上述例子进行类推。
了解了Java的位运算之后,来看下 Integer.highestOneBit (i) 这个函数的实现代码:
[java] view plain copy print?
publicstaticinthighestOneBit(int i) {
// HD, Figure 3-1
i |= (i >> 1);
i |= (i >> 2);
i |= (i >> 4);
i |= (i >>
;
i |= (i >> 16);
return i - (i >>> 1);
}
1、第一步的作用是把最高位1右移移位,并与原数据按位取或。那么这就使得最高位和它的下一位是连续两个1。
2、第二步的作用是把刚刚移位得到连续两个1继续右移两位并与原数据按位取或。那么这就使得最高两位和它的下两个连续位组成四个连续的1。
3、 以此类推,最终得到的i是从开始的最高位到结束全是1。并减去i不带符号的右移一位,即可得到一个int数据的最高位的值。
4、上述情况是针对于i不为零和负数的情况,如果i为零,那么得到的结果始终为零。如果i位负数,那么得到的结果始终是-2147483648。即等于Integer.MIN_VALUE。(原因在于负数的最高位始终为1,即是负数的符号位)
此函数的最重要理解点在与要始终把握二进制的最高位进行运算处理,那么对于函数中的右移一位、两位、四位、八和十六位就好理解了。同理,对于long类型的取最高位运算应该需要加一条语句 i|=(i>>32); 原因在于long类型在Java中是64位的。
Long类型的hightestOneBit(i)代码如下:
[java] view plain copy print?
public static long highestOneBit(long i) {
// HD, Figure 3-1
i |= (i >> 1);
i |= (i >> 2);
i |= (i >> 4);
i |= (i >>
;
i |= (i >> 16);
i |= (i >> 32);
return i - (i >>> 1);
}
来自: http://blog.csdn.net/jessenpan/article/details/9617749
分享到:
相关推荐
Java Integer.valueOf()和Integer.parseInt()的区别说明 Java 中的 Integer 类中有两个静态方法,Integer.valueOf(String s) 和 Integer.parseInt(String s),它们都可以将字符串转换为整型,但它们之间有着很大的...
Java Integer.ValueOf()的一些了解 在Java中,Integer.ValueOf()方法是一个非常重要的方法,它可以将整数类型的值转换为Integer对象。下面我们就来详细了解一下这个方法的实现原理和使用方式。 首先,让我们来看...
HugeInteger.java
在Java中,`Integer.parseInt()` 和 `Integer.valueOf()` 方法默认将字符串转换为32位有符号整数。这意味着它们能够处理的范围是 `-2^31` 到 `2^31 - 1`,即 `-2147483648` 到 `2147483647`。因此,当试图将 `'...
例如,`Integer.toHexString()`可以将十进制整数转换为十六进制字符串,`Integer.toBinaryString()`用于转换为二进制,而`Integer.toOctalString()`则用于转换为八进制。反之,要将其他进制的字符串转换为十进制,...
Java.sql.Date date = new Java.sql.Date(Integer.parseInt(st.nextToken()), Integer.parseInt(st.nextToken()), Integer.parseInt(st.nextToken())); 在实际应用中,我们需要注意Java.util.Date和Java.sql.Date的...
Java.lang.NumberFormatException错误及解决办法 ...通过使用Integer.parseInt()方法,并判断该数据是否为空,或者是否符合数字格式的规则,我们可以避免Java.lang.NumberFormatException错误的发生。
import java.io.*; public class FirstPart{ public static void main(String[] ...int f = Integer.parseInt(br.readLine()); double c=5*(f-32); c=c/9; System.out.println("Changing it to Celsius is "+c); } }
Java中Integer.valueOf、parsetInt() String.valueOf的区别和结果代码解析 Java中Integer.valueOf、parsetInt()和String.valueOf都是常用的方法,但是它们之间存在着很多的区别,下面我们将通过代码来解释它们之间...
Demo03Integer.java
.Integer, .Integer, .Integer, .Integer, .Integer, .Integer, .Integer, .Integer, .Integer, .Integer, .Integer, .Integer, .Integer, .Integer, .Integer, .Integer, .Integer, .Integer, .Integer, .Integer, ...
java java_leetcode题解之Complement of Base 10 Integer.java
在Java编程语言中,`Integer.valueOf()`方法是一个关键的知识点,尤其对于理解自动装箱(autoboxing)和拆箱(unboxing)机制至关重要。在Java中,基本类型`int`与封装类`Integer`之间可以自动转换,这就是所谓的...
java基础 leetcode java 题解之 Add to Array-Form of Integer.java
例如,`java.lang`包是最基础的包,包含了一些基本类型类的包装类,如`Integer`、`String`,以及系统相关的类,如`System`、`Class`。`java.util`包提供了集合框架、日期时间、队列、映射等工具类。`java.io`和`java...
在Java编程环境中,"java.security.InvalidKeyException: illegal Key Size" 是一个常见的错误,通常发生在加密或解密操作中。这个错误表示你试图使用的密钥长度超过了Java默认的安全限制。在给定的上下文中,这个...
String str = Integer.toString(i);` * 使用字符串连接操作:`int i = 42; String str = "" + i;` 浮点型到字符串 将浮点型变量转换为字符串可以使用以下方法: * 使用 `Double.toString()` 方法:`double d = ...
Java.util.ConcurrentModificationException 异常问题详解 ConcurrentModificationException 异常是 Java 中一个常见的异常,它发生在 Iterator 遍历集合时,集合同时被修改引起的异常。在 Java 中,集合类如 ...
Java是一种广泛使用的面向对象的编程语言,其设计目标是具有高度的可移植性,可以在不同...理解这些概念对于编写高效、可靠的Java代码至关重要。在实际编程中,合理利用Integer缓存池可以显著减少内存消耗和提高性能。
在 Java 编程中,`BigDecimal` 和 `Integer` 是两个不同类型的数值表示。`BigDecimal` 用于处理精确的浮点数运算,适合财务或金融计算,因为它可以避免浮点数计算中的精度问题。而 `Integer` 是 Java 中的整数类型,...