📄 chapter03.html
字号:
you can get a potential performance increase if all the parts of a logical
expression do not need to be
evaluated.</FONT><A NAME="_Toc375545254"></A><A NAME="_Toc408018455"></A><BR></P></DIV>
<A NAME="Heading110"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
Bitwise operators<A NAME="Index154"></A><A NAME="Index155"></A></H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The bitwise operators allow you to
manipulate individual bits in an integral primitive data type. Bitwise operators
perform boolean algebra<A NAME="Index156"></A> on the corresponding bits in the
two arguments to produce the result.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The bitwise operators come from
C’s low-level orientation; you were often manipulating hardware directly
and had to set the bits in hardware registers. Java was originally designed to
be embedded in TV <A NAME="Index157"></A>set-top boxes, so this low-level
orientation still made sense. However, you probably won’t use the bitwise
operators much.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The bitwise AND operator
(&)<A NAME="Index158"></A><A NAME="Index159"></A> produces a one in the
output bit if both input bits are one; otherwise it produces a zero. The bitwise
OR operator (|)<A NAME="Index160"></A><A NAME="Index161"></A> produces a one in
the output bit if either input bit is a one and produces a zero only if both
input bits are zero. The bitwise, EXCLUSIVE OR, or XOR
(^),<A NAME="Index162"></A><A NAME="Index163"></A><A NAME="Index164"></A>
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><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">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><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">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><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The <B>boolean</B> 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 <B>boolean</B>s the bitwise operators have
the same effect as the logical operators except that they do not short circuit.
Also, the bitwise operators on <B>boolean</B>s gives you a XOR logical operator
that is not included under the list of “logical” operators.
You’re prevented from using <B>boolean</B>s in shift expressions, which is
described
next.</FONT><A NAME="_Toc375545255"></A><A NAME="_Toc408018456"></A><BR></P></DIV>
<A NAME="Heading111"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
Shift operators<A NAME="Index175"></A><A NAME="Index176"></A></H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The shift operators also manipulate
bits. They can be used solely with primitive, integral types. The left-shift
operator (<B><<</B>)<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
(<B>>></B>)<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 <B>>> </B>uses
<I>sign extension</I>: 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 <B>>>>,
</B>which<B> </B>uses <I>zero extension</I>: regardless of the sign, zeroes are
inserted at the higher-order bits.<I> </I>This operator does not exist in C or
C++.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">If you shift a <B>char</B>,
<B>byte,</B> or <B>short</B>, it will be promoted to <B>int</B> before the shift
takes place, and the result will be an <B>int</B>. 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 <B>int</B>. If you’re operating on a <B>long</B>,
<B>long</B> 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
<B>long</B>. There is a problem, however, with the unsigned right shift. If you
use it with <B>byte</B> or <B>short</B> 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 <B>int</B> and right shifted,
but the zero extension does <I>not</I> occur, so you get <B>-1</B> in those
cases. The following example can be used to test your
implementation:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><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>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Shifts can be combined with the
equal sign (<B><<=</B> or <B>>>=</B> or
<B>>>>=</B>)<A NAME="Index183"></A><A NAME="Index184"></A>. The lvalue
is replaced by the lvalue shifted by the rvalue.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Here’s an example that
demonstrates the use of all the operators involving bits:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><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(<font color=#004488>"-1"</font>, -1);
pBinInt(<font color=#004488>"+1"</font>, +1);
<font color=#0000ff>int</font> maxpos = 2147483647;
pBinInt(<font color=#004488>"maxpos"</font>, maxpos);
<font color=#0000ff>int</font> maxneg = -2147483648;
pBinInt(<font color=#004488>"maxneg"</font>, maxneg);
pBinInt(<font color=#004488>"i"</font>, i);
pBinInt(<font color=#004488>"~i"</font>, ~i);
pBinInt(<font color=#004488>"-i"</font>, -i);
pBinInt(<font color=#004488>"j"</font>, j);
pBinInt(<font color=#004488>"i & j"</font>, i & j);
pBinInt(<font color=#004488>"i | j"</font>, i | j);
pBinInt(<font color=#004488>"i ^ j"</font>, i ^ j);
pBinInt(<font color=#004488>"i << 5"</font>, i << 5);
pBinInt(<font color=#004488>"i >> 5"</font>, i >> 5);
pBinInt(<font color=#004488>"(~i) >> 5"</font>, (~i) >> 5);
pBinInt(<font color=#004488>"i >>> 5"</font>, i >>> 5);
pBinInt(<font color=#004488>"(~i) >>> 5"</font>, (~i) >>> 5);
<font color=#0000ff>long</font> l = rand.nextLong();
<font color=#0000ff>long</font> m = rand.nextLong();
pBinLong(<font color=#004488>"-1L"</font>, -1L);
pBinLong(<font color=#004488>"+1L"</font>, +1L);
<font color=#0000ff>long</font> ll = 9223372036854775807L;
pBinLong(<font color=#004488>"maxpos"</font>, ll);
<font color=#0000ff>long</font> lln = -9223372036854775808L;
pBinLong(<font color=#004488>"maxneg"</font>, lln);
pBinLong(<font color=#004488>"l"</font>, l);
pBinLong(<font color=#004488>"~l"</font>, ~l);
pBinLong(<font color=#004488>"-l"</font>, -l);
pBinLong(<font color=#004488>"m"</font>, m);
pBinLong(<font color=#004488>"l & m"</font>, l & m);
pBinLong(<font color=#004488>"l | m"</font>, l | m);
pBinLong(<font color=#004488>"l ^ m"</font>, l ^ m);
pBinLong(<font color=#004488>"l << 5"</font>, l << 5);
pBinLong(<font color=#004488>"l >> 5"</font>, l >> 5);
pBinLong(<font color=#004488>"(~l) >> 5"</font>, (~l) >> 5);
pBinLong(<font color=#004488>"l >>> 5"</font>, l >>> 5);
pBinLong(<font color=#004488>"(~l) >>> 5"</font>, (~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=#004488>", int: "</font> + i + <font color=#004488>", binary: "</font>);
System.out.print(<font color=#004488>" "</font>);
<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(<font color=#004488>"1"</font>);
<font color=#0000ff>else</font>
System.out.print(<font color=#004488>"0"</font>);
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=#004488>", long: "</font> + l + <font color=#004488>", binary: "</font>);
System.out.print(<font color=#004488>" "</font>);
<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(<font color=#004488>"1"</font>);
<font color=#0000ff>else</font>
System.out.print(<font color=#004488>"0"</font>);
System.out.println();
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The two methods at the end,
<B>pBinInt( )</B> and <B>pBinLong( )</B> take an <B>int</B> or a
<B>long</B>, respectively, and print it out in binary format along with a
descriptive string. You can ignore the implementation of these for
now.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You’ll note the use of
<B>System.out.print( )</B> instead of <B>System.out.println( )</B>.
The <B>print( )</B> method does not put out a new line, so it allows you to
output a line in pieces.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">As well as demonstrating the effect
of all the bitwise operators for <B>int</B> and <B>long</B>, this example also
shows the minimum, maximum, +1 and -1 values for <B>int</B> and <B>long</B> so
you can see what they look like. Note that the high bit represents the sign: 0
means positive and 1 means negative. The output for the <B>int</B> portion looks
like this:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE>-1, <font color=#0000ff>int</font>: -1, binary:
11111111111111111111111111111111
+1, <font color=#0000ff>int</font>: 1, binary:
00000000000000000000000000000001
maxpos, <font color=#0000ff>int</font>: 2147483647, binary:
01111111111111111111111111111111
maxneg, <font color=#0000ff>int</font>: -2147483648, binary:
10000000000000000000000000000000
i, <font color=#0000ff>int</font>: 59081716, binary:
00000011100001011000001111110100
~i, <font color=#0000ff>int</font>: -59081717, binary:
11111100011110100111110000001011
-i, <font color=#0000ff>int</font>: -59081716, binary:
11111100011110100111110000001100
j, <font color=#0000ff>int</font>: 198850956, binary:
00001011110110100011100110001100
i & j, <font color=#0000ff>int</font>: 58720644, binary:
00000011100000000000000110000100
i | j, <font color=#0000ff>int</font>: 199212028, binary:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -