📄 tij0044.html
字号:
produces a one in the output bit if one or the other input bit is a one, but
not both. The bitwise NOT<A NAME="Index165"></A>
(~, also called the ones complement operator<A NAME="Index166"></A><A NAME="Index167"></A>)
is a unary operator;<A NAME="Index168"></A><A NAME="Index169"></A>
it takes only one argument. (All other bitwise operators are binary operators.<A NAME="Index170"></A><A NAME="Index171"></A>)
Bitwise NOT produces the opposite of the input bit – a one if the input
bit is zero, a zero if the input bit is one.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
bitwise operators and logical operators use the same characters, so it is
helpful to have a mnemonic device to help you remember the meanings: since bits
are “small,” there is only one character in the bitwise operators.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Bitwise
operators can be combined with the = sign to unite the operation and
assignment: &=<A NAME="Index172"></A>,
|=<A NAME="Index173"></A>
and ^=<A NAME="Index174"></A>
are all legitimate. (Since ~ is a unary operator it cannot be combined with the
= sign.)
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>boolean</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
type is treated as a one-bit value so it is somewhat different. You can perform
a bitwise AND, OR and XOR, but you can’t perform a bitwise NOT
(presumably to prevent confusion with the logical NOT). For
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>boolean</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">s
the bitwise operators have the same effect as the logical operators except that
they do not short circuit. Also, the bitwise operators on
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>boolean</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">s
gives you a XOR logical operator that is not included under the list of
“logical” operators. You’re prevented from using
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>boolean</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">s
in shift expressions, which is described next.
</FONT><a name="_Toc375545255"></a><a name="_Toc408018456"></a><P></DIV>
<A NAME="Heading112"></A><H3 ALIGN=LEFT>
Shift
operators<A NAME="Index175"></A><A NAME="Index176"></A></H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
shift operators also manipulate bits. They can be used solely with primitive,
integral types. The left-shift operator (
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B><<</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">)<A NAME="Index177"></A><A NAME="Index178"></A>
produces the operand to the left of the operator shifted to the left by the
number of bits specified after the operator (inserting zeroes at the
lower-order bits). The signed right-shift operator (
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>>></B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">)<A NAME="Index179"></A><A NAME="Index180"></A>
produces the operand to the left of the operator shifted to the right by the
number of bits specified after the operator. The signed right shift
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>>>
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">uses
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>sign
extension
</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">:
if the value is positive, zeroes are inserted at the higher-order bits; if the
value is negative, ones are inserted at the higher-order bits. Java has also
added the unsigned right shift
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>>>>,
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">which</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">uses
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>zero
extension
</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">:
regardless of the sign, zeroes are inserted at the higher-order bits.
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>
</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">This
operator does not exist in C or C++.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">If
you shift a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>char</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>byte,</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
or
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>short</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
it will be promoted to
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>int</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
before the shift takes place, and the result will be an
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>int</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
Only the five low-order bits of the right-hand side will be used. This prevents
you from shifting more than the number of bits in an
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>int</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
If you’re operating on a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>long</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>long</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
will be the result. Only the six low-order bits of the right-hand side will be
used so you can’t shift more than the number of bits in a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>long</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
There is a problem, however, with the unsigned right shift. If you use it with
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>byte</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
or
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>short</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
you might not get the correct results. (It’s broken in <A NAME="Index181"></A>Java
1.0 and Java 1.1.<A NAME="Index182"></A>)
These are promoted to
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>int</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and right shifted, but the zero extension does
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>not</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
occur, so you get
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>-1</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
in those cases. The following example can be used to test your implementation:
</FONT><P></DIV>
<font color="#990000"><PRE><font color="#009900">//: URShift.java</font>
<font color="#009900">// Test of unsigned right shift</font>
<font color="#0000ff">public</font> <font color="#0000ff">class</font> URShift {
<font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
<font color="#0000ff">int</font> i = -1;
i >>>= 10;
System.out.println(i);
<font color="#0000ff">long</font> l = -1;
l >>>= 10;
System.out.println(l);
<font color="#0000ff">short</font> s = -1;
s >>>= 10;
System.out.println(s);
<font color="#0000ff">byte</font> b = -1;
b >>>= 10;
System.out.println(b);
}
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Shifts
can be combined with the equal sign (
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B><<=</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
or
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>>>=</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
or
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>>>>=</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">)<A NAME="Index183"></A><A NAME="Index184"></A>.
The lvalue is replaced by the lvalue shifted by the rvalue.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Here’s
an example that demonstrates the use of all the operators involving bits:
</FONT><P></DIV>
<font color="#990000"><PRE><font color="#009900">//: BitManipulation.java</font>
<font color="#009900">// Using the bitwise operators</font>
<font color="#0000ff">import</font> java.util.*;
<font color="#0000ff">public</font> <font color="#0000ff">class</font> BitManipulation {
<font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
Random rand = <font color="#0000ff">new</font> Random();
<font color="#0000ff">int</font> i = rand.nextInt();
<font color="#0000ff">int</font> j = rand.nextInt();
pBinInt("-1", -1);
pBinInt("+1", +1);
<font color="#0000ff">int</font> maxpos = 2147483647;
pBinInt("maxpos", maxpos);
<font color="#0000ff">int</font> maxneg = -2147483648;
pBinInt("maxneg", maxneg);
pBinInt("i", i);
pBinInt("~i", ~i);
pBinInt("-i", -i);
pBinInt("j", j);
pBinInt("i & j", i & j);
pBinInt("i | j", i | j);
pBinInt("i ^ j", i ^ j);
pBinInt("i << 5", i << 5);
pBinInt("i >> 5", i >> 5);
pBinInt("(~i) >> 5", (~i) >> 5);
pBinInt("i >>> 5", i >>> 5);
pBinInt("(~i) >>> 5", (~i) >>> 5);
<font color="#0000ff">long</font> l = rand.nextLong();
<font color="#0000ff">long</font> m = rand.nextLong();
pBinLong("-1L", -1L);
pBinLong("+1L", +1L);
<font color="#0000ff">long</font> ll = 9223372036854775807L;
pBinLong("maxpos", ll);
<font color="#0000ff">long</font> lln = -9223372036854775808L;
pBinLong("maxneg", lln);
pBinLong("l", l);
pBinLong("~l", ~l);
pBinLong("-l", -l);
pBinLong("m", m);
pBinLong("l & m", l & m);
pBinLong("l | m", l | m);
pBinLong("l ^ m", l ^ m);
pBinLong("l << 5", l << 5);
pBinLong("l >> 5", l >> 5);
pBinLong("(~l) >> 5", (~l) >> 5);
pBinLong("l >>> 5", l >>> 5);
pBinLong("(~l) >>> 5", (~l) >>> 5);
}
<font color="#0000ff">static</font> <font color="#0000ff">void</font> pBinInt(String s, <font color="#0000ff">int</font> i) {
System.out.println(
s + ", <font color="#0000ff">int</font>: " + i + ", binary: ");
System.out.print(" ");
<font color="#0000ff">for</font>(<font color="#0000ff">int</font> j = 31; j >=0; j--)
<font color="#0000ff">if</font>(((1 << j) & i) != 0)
System.out.print("1");
<font color="#0000ff">else</font>
System.out.print("0");
System.out.println();
}
<font color="#0000ff">static</font> <font color="#0000ff">void</font> pBinLong(String s, <font color="#0000ff">long</font> l) {
System.out.println(
s + ", <font color="#0000ff">long</font>: " + l + ", binary: ");
System.out.print(" ");
<font color="#0000ff">for</font>(<font color="#0000ff">int</font> i = 63; i >=0; i--)
<font color="#0000ff">if</font>(((1L << i) & l) != 0)
System.out.print("1");
<font color="#0000ff">else</font>
System.out.print("0");
System.out.println();
}
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
two methods at the end,
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>pBinInt( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>pBinLong( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
take an
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>int</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
or a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>long</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
respectively,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -