JAVA位运算符 java中位运算符"|","&"怎么运算?

\u4ec0\u4e48\u662fJava\u7684\u4f4d\u8fd0\u7b97\u7b26\uff1f

\u4f4d\u8fd0\u7b97\u7b26\u7528\u6765\u5bf9\u4e8c\u8fdb\u5236\u4f4d\u8fdb\u884c\u64cd\u4f5c,\u4f4d
\u8fd0
\u7b97
\u7b26
(\uff1e\uff1e,\uff1c\uff1c,\uff1e\uff1e\uff1e,&,|,^,\uff5e
)
,\u4f4d\u8fd0
\u7b97
\u7b26
\u4e2d
,\u9664
\uff5e
\u4ee5
\u5916
,\u5176\u4f59
\u5747
\u4e3a
\u4e8c
\u5143
\u8fd0
\u7b97
\u7b26
\u3002
\u64cd
\u4f5c
\u6570
\u53ea
\u80fd
\u4e3a
\u6574
\u578b
\u548c\u5b57
\u7b26
\u578b
\u6570
\u636e
\u3002
\u6bd4\u5982\u2018>>\u2019
\u8fd9\u4e2a\u5c31\u76f8\u5f53\u4e8e\u4e58\u4ee52.

\u4f4d\u8fd0\u7b97\u7b26
\u8981\u628a\u503c\u8f6c\u6362\u6210\u4e8c\u8fdb\u5236\u6570\u8fd0\u7b97
10|1=1010|0001=1011=11
10&1=1010&0001=0000=0
\u5927\u6982

位操作符(bitwise operator)
位操作符允许我们操作一个基本数据类型中的整数型值的单个“比特(bit)”,即二进制位。
位操作符会对两个参数对应的位执行布尔代数运算,并最终生成一个结果。

位操作符来源于 C 语言面向底层的操作,那时我们经常需要直接操纵硬件,设置硬件寄存
器内的二进制位。Java的设计初衷是嵌入电视机顶盒内,所以这种低级操作仍被保留了下来。
但是,我们可能不会过多地使用到位运算符。

如果两个输入位都是 1,则按位“与”操作符(&)生成一个输出位 1;否则生成一个输出
位0。如果两个输入位里只要有一个是1,则按位“或”操作符(|)生成一个输出位1;只
有在两个输入位都是0的情况下,它才会生成一个输出位0。如果两个输入位的某一个是1,
但不全都是1,那么“异或”操作(^)生成一个输出位1。按位“非”(~ ,也称为取补运
算,ones compliement operator )属于一元操作符;它只对一个操作数进行操作(其他位操
作是二元运算)。按位“非”生成与输入位相反的值——若输入0,则输出1;输入1,则输
出0。

位操作符和逻辑操作符都使用了同样的符号。因此,我们能方便地记住它们的含义:由于“位”
是非常“小”的,所以位操作符仅使用了一位符号。

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

我们将布尔类型(boolean)作为一种“单比特”值对待,所以它多少有些独特的地方。我们

可对它执行按位“与”、“或”和“异或”运算,但不能执行按位“非”(大概是为了避免与
逻辑 NOT 混淆)。对于布尔值,位操作符具有与逻辑操作符相同的效果,只是它们不会中
途“短路”。此外,针对布尔值进行的按位运算为我们新增了一个“异或”逻辑操作符,它并
未包括在“逻辑”操作符的列表中。在移位表达式中,我们被禁止使用布尔运算,原因将在下
面解释。

移位操作符(shift operator)
移位操作符操作的运算对象也是二进制的“位”,但是它们只可以被用来处理整数类型(基本
类型的一种)。左移位操作符(<<)能将操作符左边的运算对象向左移动操作符右侧指定的
位数(在低位补 0)。“有符号”右移位操作符(>>)则将操作符左边的运算对象向右移动操
作符右侧指定的位数。“有符号”右移位操作符使用了“符号扩展”:若符号为正,则在高位插
入0;若符号为负,则在高位插入1。Java中增加了一种“无符号”右移位操作符(>>>),它
使用了“零扩展”:无论正负,都在高位插入0。这一操作符是C或C++没有的。

如果对char、byte或者short类型的数值进行移位处理,那么在移位进行之前,它们会自动
转换为int,并且得到的结果也是一个int类型的值。而右侧操作数,作为真正移位的位数,
只有其二进制表示中的低5位才有用。这样可防止我们移位超过int型值所具有的位数。(译
注:因为2的5次方为32,而int型值只有32位)。若对一个long类型的数值进行处理,
最后得到的结果也是long。此时只会用到右侧操作数的低6位,以防止移位超过long型数
值具有的位数。

移位可与等号(<<=或>>=或>>>=)组合使用。此时,操作符左边的值会移动由右边的值指
定的位数,再将得到的结果赋回左边的变量。但在进行“无符号”右移结合赋值操作时,可能
会遇到一个问题:如果对byte或short值进行这样的移位运算,得到的可能不是正确的结果。
它们会先被转换成int类型,再进行右移操作。然后被截断,赋值给原来的类型,在这种情
况下可能得到-1的结果。下面这个例子演示了这种情况:

//: c03:URShift.java
// Test of unsigned right shift.
import com.bruceeckel.simpletest.*;

public class URShift {
static Test monitor = new Test();
public static void main(String[] args) {
int i = -1;
System.out.println(i >>>= 10);
long l = -1;
System.out.println(l >>>= 10);
short s = -1;
System.out.println(s >>>= 10);
byte b = -1;
System.out.println(b >>>= 10);

b = -1;
System.out.println(b>>>10);
monitor.expect(new String[] {
"4194303",
"18014398509481983",
"-1",
"-1",
"4194303"
});
}
} ///:~

在最后一个移位运算中,结果没有赋回给b,而是直接打印出来,所以其结果是正确的。

下面这个例子向大家阐示了如何应用涉及“按位”操作的所有操作符:

//: c03:BitManipulation.java
// Using the bitwise operators.
import com.bruceeckel.simpletest.*;
import java.util.*;

public class BitManipulation {
static Test monitor = new Test();
public static void main(String[] args) {
Random rand = new Random();
int i = rand.nextInt();
int j = rand.nextInt();
printBinaryInt("-1", -1);
printBinaryInt("+1", +1);
int maxpos = 2147483647;
printBinaryInt("maxpos", maxpos);
int maxneg = -2147483648;
printBinaryInt("maxneg", maxneg);
printBinaryInt("i", i);
printBinaryInt("~i", ~i);
printBinaryInt("-i", -i);
printBinaryInt("j", j);
printBinaryInt("i & j", i & j);
printBinaryInt("i | j", i | j);
printBinaryInt("i ^ j", i ^ j);
printBinaryInt("i << 5", i << 5);
printBinaryInt("i >> 5", i >> 5);
printBinaryInt("(~i) >> 5", (~i) >> 5);
printBinaryInt("i >>> 5", i >>> 5);

printBinaryInt("(~i) >>> 5", (~i) >>> 5);

long l = rand.nextLong();
long m = rand.nextLong();
printBinaryLong("-1L", -1L);
printBinaryLong("+1L", +1L);
long ll = 9223372036854775807L;
printBinaryLong("maxpos", ll);
long lln = -9223372036854775808L;
printBinaryLong("maxneg", lln);
printBinaryLong("l", l);
printBinaryLong("~l", ~l);
printBinaryLong("-l", -l);
printBinaryLong("m", m);
printBinaryLong("l & m", l & m);
printBinaryLong("l | m", l | m);
printBinaryLong("l ^ m", l ^ m);
printBinaryLong("l << 5", l << 5);
printBinaryLong("l >> 5", l >> 5);
printBinaryLong("(~l) >> 5", (~l) >> 5);
printBinaryLong("l >>> 5", l >>> 5);
printBinaryLong("(~l) >>> 5", (~l) >>> 5);
monitor.expect("BitManipulation.out");
}
static void printBinaryInt(String s, int i) {
System.out.println(
s + ", int: " + i + ", binary: ");
System.out.print(" ");
for(int j = 31; j >= 0; j--)
if(((1 << j) & i) != 0)
System.out.print("1");
else
System.out.print("0");
System.out.println();
}
static void printBinaryLong(String s, long l) {
System.out.println(
s + ", long: " + l + ", binary: ");
System.out.print(" ");
for(int i = 63; i >= 0; i--)
if(((1L << i) & l) != 0)
System.out.print("1");
else
System.out.print("0");

System.out.println();
}
} ///:~

程序末尾调用了两个方法:printBinaryInt()和printBinaryLong()。它们分别接受
一个 int 或 long 值的参数,并用二进制格式输出,同时附有简要的说明文字。你可以暂
时忽略它们具体是如何实现的。

请注意这里是用 System.out.print(),而不是 System.out.println()。print()方法不自动换行,所
以我们能在同一行里输出多个信息。

上面的例子中,expect() 以一个文件名作参数,它会从这个文件中读取预期的行(其中
可以有,也可以没有正则表达式)。对于那些太长,不适宜列在书里的输出,这种做法很有
用。这个文件的扩展名是“.out”,是所发布的代码的一部分,可以从www.BruceEckel.com下
载。如果有兴趣的话,可以打开这个文件,看看正确的输出应该是什么(或者你自己直接运
行一下前面这个程序)。

上面的例子展示了对int和long的所有按位运算的效果,还展示了int和long的最小值、最
大值、+1和-1值,以及它们的二进制形式,以使大家了解它们在机器中的具体形式。注意,
最高位表示符号:0为正,1为负。下面列出例子中关于int部分的输出:

-1, int: -1, binary:
11111111111111111111111111111111
+1, int: 1, binary:
00000000000000000000000000000001
maxpos, int: 2147483647, binary:
01111111111111111111111111111111
maxneg, int: -2147483648, binary:
10000000000000000000000000000000
i, int: 59081716, binary:
00000011100001011000001111110100
~i, int: -59081717, binary:
11111100011110100111110000001011
-i, int: -59081716, binary:
11111100011110100111110000001100
j, int: 198850956, binary:
00001011110110100011100110001100
i & j, int: 58720644, binary:
00000011100000000000000110000100
i | j, int: 199212028, binary:
00001011110111111011101111111100
i ^ j, int: 140491384, binary:
00001000010111111011101001111000
i << 5, int: 1890614912, binary:

01110000101100000111111010000000
i >> 5, int: 1846303, binary:
00000000000111000010110000011111
(~i) >> 5, int: -1846304, binary:
11111111111000111101001111100000
i >>> 5, int: 1846303, binary:
00000000000111000010110000011111
(~i) >>> 5, int: 132371424, binary:
00000111111000111101001111100000

数字的二进制表示形式被称为“有符号的2的补码”。

  • JAVA浣嶈繍绠楃
    绛旓細1锛庝笌杩愮畻绗 涓庤繍绠楃鐢ㄧ鍙封&鈥濊〃绀猴紝鍏朵娇鐢ㄨ寰嬪涓嬶細涓や釜鎿嶄綔鏁颁腑浣嶉兘涓1锛岀粨鏋滄墠涓1锛屽惁鍒欑粨鏋滀负0锛屼緥濡備笅闈㈢殑绋嬪簭娈点俻ublic class data13 { public static void main(String[] args){ int a=129;int b=128;System.out.println("a 鍜宐 涓庣殑缁撴灉鏄細"+(a&b));} } 杩愯缁撴灉 a ...
  • JAVA浣嶈繍绠鎬庝箞鐢ㄧ殑???
    绛旓細Java 浣嶈繍绠 Java 浣嶈繍绠梉杞琞涓锛孞ava 浣嶈繍绠1.琛ㄧず鏂规硶锛氥鍦↗ava璇█涓紝浜岃繘鍒舵暟浣跨敤琛ョ爜琛ㄧず锛屾渶楂樹綅涓虹鍙蜂綅锛屾鏁扮殑绗﹀彿浣嶄负0锛岃礋鏁颁负1銆傝ˉ鐮佺殑琛ㄧず闇瑕佹弧瓒冲涓嬭姹傘傘(l)姝f暟鐨勬渶楂樹綅涓0锛屽叾浣欏悇浣嶄唬琛ㄦ暟鍊兼湰韬(浜岃繘鍒舵暟)銆傘(2)瀵逛簬璐熸暟锛岄氳繃瀵硅鏁扮粷瀵瑰肩殑琛ョ爜鎸変綅鍙栧弽锛屽啀瀵...
  • JAVA浣嶈繍绠楃
    绛旓細浣嶆搷浣滅鏉ユ簮浜 C 璇█闈㈠悜搴曞眰鐨勬搷浣,閭f椂鎴戜滑缁忓父闇瑕佺洿鎺ユ搷绾电‖浠,璁剧疆纭欢瀵勫瓨鍣ㄥ唴鐨勪簩杩涘埗浣嶃Java鐨勮璁″垵琛锋槸宓屽叆鐢佃鏈洪《鐩掑唴,鎵浠ヨ繖绉嶄綆绾ф搷浣滀粛琚繚鐣欎簡涓嬫潵銆備絾鏄,鎴戜滑鍙兘涓嶄細杩囧鍦颁娇鐢ㄥ埌浣嶈繍绠楃銆 濡傛灉涓や釜杈撳叆浣嶉兘鏄 1,鍒欐寜浣嶁滀笌鈥濇搷浣滅(&)鐢熸垚涓涓緭鍑轰綅 1;鍚﹀垯鐢熸垚涓涓緭鍑轰綅0銆傚鏋滀袱涓...
  • 姹:JAVA涓父鐢浣嶈繍绠楃鍙婂叾鐢ㄦ硶璇﹁В
    绛旓細int z = x&y //z绛変簬浜岃繘鍒舵暟鐨01000000 鍗杩愮畻缁撴灉涓簔绛変簬浜岃繘鍒舵暟01000000銆備綅鎴栥佷綅闈炪佷綅寮傛垨鐨勮繍绠楁柟娉曠被鍚屻傦紙2锛夊彸绉绘槸灏嗕竴涓簩杩涘埗鏁版寜鎸囧畾绉诲姩鐨勪綅鏁板悜鍙崇Щ浣嶏紝绉绘帀鐨勮涓㈠純锛屽乏杈圭Щ杩涚殑閮ㄥ垎鎴栬呰ˉ0锛堝綋璇ユ暟涓烘鏃讹級锛屾垨鑰呰ˉ1锛堝綋璇ユ暟涓鸿礋鏃讹級銆傝繖鏄洜涓烘暣鏁板湪鏈哄櫒鍐呴儴閲囩敤琛ョ爜...
  • JAVA涓&&鍜&銆亅|鍜寍鐨勫尯鍒?
    绛旓細鈥1銆Java涓&鍙仛鎸変綅涓,&&鍙仛鐭矾涓,瀹冧滑鐨勫尯鍒槸: & 鏃㈡槸浣嶈繍绠楃鍙堟槸閫昏緫杩愮畻绗,&鐨勪袱渚у彲浠ユ槸int,涔熷彲浠ユ槸boolean琛ㄨ揪寮,褰&涓や晶鏄痠nt鏃,瑕佸厛鎶婅繍绠楃涓や晶鐨勬暟杞寲涓轰簩杩涘埗鏁板啀杩涜杩愮畻,鑰岀煭璺笌(&&)鐨勪袱渚ц姹傚繀椤绘槸甯冨皵琛ㄨ揪寮忋備妇渚嬪涓:12&5 鐨勫兼槸澶氬皯...鈥...
  • Java涓&鏄粈涔堟剰鎬?
    绛旓細&鍦java涓〃绀浣嶈繍绠楃鍗筹紝鎸変綅涓庤繍绠椼傜敤鏉ュ浜岃繘鍒朵綅杩涜鎿嶄綔锛屼负浜屽厓杩愮畻绗︼紝鏅鸿兘涓烘暣鍨嬪拰瀛楃鍨嬫暟鎹傚鏋滀袱涓繍绠楁暟閮芥槸1锛屽垯缁撴灉涓1.鍏朵粬鎯呭喌涓嬶紝缁撴灉鍧囦负闆讹細00101010(鍗佽繘鍒跺间负42)&00001111(鍗佽繘鍒跺间负15)=00001010(鍗佽繘鍒跺10)鑰屽湪java璇█涓 i1&=3鐨勮〃杈惧紡鐨勫睍寮褰㈠紡涓猴細i1=i1&3,...
  • java杩愮畻涓&鏄粈涔堟剰鎬,姣斿a=1;b=2;a&b=澶氬皯
    绛旓細&鏄綅鎿嶄綔绗,鈥滄寜浣嶄笌鈥濓紱1杞垚浜岃繘鍒 01锛2杞垚浜岃繘鍒 10锛沘&b=00杞垚鍗佽繘鍒朵负0銆浣嶈繍绠楃鏈夛細&(鎸変綅涓)銆亅(鎸変綅鎴)銆乛(鎸変綅寮傛垨)銆亊 (鎸変綅鍙栧弽)銆備紭鍏堢骇浠庨珮鍒颁綆锛屼緷娆′负~銆&銆乛銆亅銆傛寜浣嶄笌杩愮畻鏈変袱绉嶅吀鍨嬬敤娉曪紝涓鏄彇涓涓綅涓蹭俊鎭殑鏌愬嚑浣嶏紝濡備互涓嬩唬鐮佹埅鍙杧鐨勬渶浣7浣嶏細x ...
  • Java涓殑杩愮畻绗鏈夊摢浜
    绛旓細鍏崇郴杩愮畻绗︼細鐢ㄤ簬鍒ゆ柇涓や釜鏁版嵁鐨勫ぇ灏忔垨鐩哥瓑鍏崇郴锛岃繑鍥炰竴涓竷灏斿(true鎴杅alse)銆傚父鐢ㄧ殑鍏崇郴杩愮畻绗︽湁 < > <= >= == !=銆傞昏緫杩愮畻绗︼細鐢ㄤ簬杩涜閫昏緫涓庛侀昏緫鎴栥侀昏緫闈炵瓑鎿嶄綔锛岃繑鍥炰竴涓竷灏斿(true鎴杅alse)銆傚父鐢ㄧ殑閫昏緫杩愮畻绗︽湁 && || !銆浣嶈繍绠楃锛氱敤浜庡浜岃繘鍒朵綅杩涜鎿嶄綔锛屽鎸変綅涓庛佹寜浣嶆垨...
  • JAVA閲岄潰鐨浣嶈繍绠楃>>,<<,>>>鏄粈涔堟剰鎬,璇蜂妇涓垪瀛愬叿浣撹鏄庝竴涓?_鐧 ...
    绛旓細java 涓細>>甯︾鍙峰彸绉 (n>>2 灏嗘暣鍨嬪煎甫绗﹀彿鍙崇Щ2浣 锛<<甯︾鍙峰乏绉 (n<<2 灏嗘暣鍨嬪煎甫绗﹀彿宸︾Щ2浣 锛>>>鏃犵鍙峰彸绉 (n>>>2 灏嗘暣鍨嬪兼棤绗﹀彿鍙崇Щ2浣 锛 鍦32浣嶇郴缁熶腑浠讳綍鏁板乏绉(鍙崇Щ)32浣嶈繕鏄畠鏈韩 渚嬪:�6�1a=a锛滐紲2灏哸...
  • java涓 浠涔堟槸 鍒嗛噺杩愮畻绗• ?
    绛旓細&鏄JAVA涓殑浣嶉昏緫杩愮畻绗锛岀О鈥滄寜浣嶄笌鈥濓紝杩愮畻瑙勫垯鏄細鈥&鈥濅袱涓繍绠楁暟閮戒负1鏃讹紝缁撴灉涓1锛屽叾浣欑粨鏋滀负0锛屽嵆锛氬嵆锛0&0=0锛0&1=0锛1&0=0锛1&1=1鐢ㄩ旓細(1)娓呴浂杩愮畻瀵硅薄锛氬師鏉ョ殑鏁颁腑涓1鐨勪綅锛屾柊鏁颁腑鐩稿簲浣嶄负0銆傦紙2锛夊彇涓涓暟涓煇浜涙寚瀹氫綅銆傚鎯宠鍙栦竴涓暣鏁癮锛堝崰2涓瓧鑺傦級鐨勪綆锛堥珮...
  • 本站交流只代表网友个人观点,与本站立场无关
    欢迎反馈与建议,请联系电邮
    2024© 车视网