您的位置 首页 java

Java编程思想:按位运算符 & 移位运算符

位运算符 允许我们操作一个整数主数据类型中的单个“比特”,即二进制位。按位运算符会对两个自变量中对应的位执行 布尔代数 ,并最终生成一个结果。

位运算 来源于 C 语言的低级操作。我们经常都要直接操纵硬件,需要频繁设置硬件寄存器内的二进制位。

Java 的设计初衷是嵌入电视顶置盒内,所以这种低级操作仍被保留下来了。然而,由于操作系统的进步,现在也许不必过于频繁地进行按位运算。

若两个输入位都是 1 ,则按位 AND 运算符( & )在输出位里生成一个 1 ;否则生成 0 。若两个输入位里至少有一个是 1 ,则按位 OR 运算符( | )在输出位里生成一个 1 ;只有在两个输入位都是 0 的情况下,它才会生成一个 0 。若两个输入位的某一个是 1 ,但不全都是 1 ,那么按位 XOR ^ ,异或)在输出位里生成一个 1 。按位 NOT ~ ,也叫作“非”运算符)属于一元运算符;它只对一个自变量进行操作(其他所有运算符都是二元运算符)。按位 NOT 生成与输入位的相反的值——若输入 0 ,则输出 1 ;输入 1 ,则输出 0

按位运算符和逻辑运算符都使用了同样的字符,只是数量不同。因此,我们能方便地记忆各自的含义:由于“位”是非常“小”的,所以按位运算符仅使用了一个字符。

按位运算符可与等号( = )联合使用,以便合并运算及赋值: &= |= ^= 都是合法的(由于 ~ 是一元运算符,所以不可与 = 联合使用)。

我们将 boolean 布尔 )类型当作一种“单位”或“单比特”值对待,所以它多少有些独特的地方。我们可执行按位 AND OR XOR ,但不能执行按位 NOT (大概是为了避免与逻辑 NOT 混淆)。对于 布尔值 ,按位运算符具有与逻辑运算符相同的效果,只是它们不会中途“短路”。此外,针对布尔值进行的按位运算为我们新增了一个 XOR 逻辑运算符,它并未包括在“逻辑”运算符的列表中。在移位表达式中,我们被禁止使用 布尔运算 ,原因将在下面解释。

移位运算符

移位运算符 面向的运算对象也是二进制的“位”。可单独用它们处理整数类型(主类型的一种)。左移位运算符( << )能将运算符左边的运算对象向左移动运算符右侧指定的位数(在低位补 0 )。“有符号”右移位运算符( >> )则将运算符左边的运算对象向右移动运算符右侧指定的位数。“有符号”右移位运算符使用了 “符号扩展”:若值为正,则在高位插入 0 ;若值为负,则在高位插入 1 Java 也添加了一种“无符号”右移位运算符( >>> ),它使用了“零扩展”:无论正负,都在高位插入 0 。这一运算符是 C C++ 没有的。

若对 char byte 或者 short 进行移位处理,那么在移位进行之前,它们会自动转换成一个 int 。只有右侧的 5 个低位才会用到。这样可防止我们在一个int数里移动不切实际的位数。若对一个 long 值进行处理,最后得到的结果也是 long 。此时只会用到右侧的 6 个低位,防止移动超过 long 值里现成的位数。但在进行“无符号”右移位时,也可能遇到一个问题。若对 byte short 值进行右移位运算,得到的可能不是正确的结果(Java 1.0和Java 1.1特别突出)。它们会自动转换成 int 类型,并进行右移位。但“零扩展”不会发生,所以在那些情况下会得到 -1 的结果。可用下面这个例子检测自己的实现方案:

//: URShift.java 
// Test of unsigned right shift 
 public class URShift { 
 public static void main(String[] args) { 
 int i = -1; i >>>= 10; 
 System.out.println(i); 
 long l = -1; l >>>= 10; 
 System.out.println(l); 
 short s = -1; s >>>= 10; 
 System.out.println(s); 
 byte b = -1; b >>>= 10; 
 System.out.println(b); 
 } 
} ///:~ 
 

移位可与等号( <<= >>= >>>= )组合使用。此时,运算符左边的值会移动由右边的值指定的位数,再将得到的结果赋回左边的值。

文章来源:智云一二三科技

文章标题:Java编程思想:按位运算符 & 移位运算符

文章地址:https://www.zhihuclub.com/186631.shtml

关于作者: 智云科技

热门文章

网站地图