最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解Java的位運(yùn)算

 更新時間:2023年04月11日 10:20:33   作者:CrazyDragon_King  
這篇文章主要介紹了詳解Java的位運(yùn)算,程序中的所有數(shù)在計算機(jī)內(nèi)存中都是以二進(jìn)制的形式儲存的。位運(yùn)算就是直接對整數(shù)在內(nèi)存中的二進(jìn)制位進(jìn)行操作,需要的朋友可以參考下

位運(yùn)算

很久以前學(xué)習(xí)過位運(yùn)算,但是很久不用,感覺都忘得差不多了。最近看了幾處位運(yùn)算的代碼,發(fā)現(xiàn)都看不懂了,哈。也是時候回來補(bǔ)一補(bǔ)基礎(chǔ)知識了。

程序中的所有數(shù)在計算機(jī)內(nèi)存中都是以二進(jìn)制的形式儲存的。位運(yùn)算就是直接對整數(shù)在內(nèi)存中的二進(jìn)制位進(jìn)行操作。

位運(yùn)算的運(yùn)算符:

運(yùn)算符含義
&按位與
|按位或
~按位取反
^按位異或
<<左移
>>帶符號右移
>>>無符號右移

這些算是很基礎(chǔ)的知識了,但是太久不用,還是難免會遺忘了,在編碼的同時,可以多多使用!

Talk is cheap, show me the code.

說明:單獨(dú)討論這些確實(shí)是很難看到應(yīng)用的地方,如果有不太清楚的可以去看看其他人的總結(jié)。

我們以一個代碼來看看位運(yùn)算的應(yīng)用:

public final void writeInt(int v) throws IOException {
	  out.write((v >>> 24) & 0xFF);
	  out.write((v >>> 16) & 0xFF);
	  out.write((v >>>  8) & 0xFF);
	  out.write((v >>>  0) & 0xFF);
	  incCount(4);
}

這段代碼是 DataOutputStream 類中的一個方法,用于將一個 int 型的整數(shù)寫入流中。這個方法的命名是很有意思的,它和 OutputStream 中的 public abstract void write(int b) throws IOException 這個方法是完全不同的。這個方法的參數(shù)似乎是表示它可以將一個 int 型整數(shù)寫入流中,但是方法的功能不是靠猜測的,而是要看方法的描述。

public abstract void write(int b) throws IOException

API 中的介紹:

Writes the specified byte to this output stream. The general contract for write is that one byte is written to the output stream. The byte to be written is the eight low-order bits of the argument b. The 24 high-order bits of b are ignored.

它是將一個特定的字節(jié)寫入流中,我們知道一個int型變量占32位,一個byte占8位,所以一個小于256(2^8)的int型整數(shù)和byte型整數(shù)的最后8位是相同的。

因此這個方法是寫入一個int型變量的最低8位,而將剩下的24位忽略。使用這個方法的時候,要格外注意!

The byte to be written is the eight low-order bits of the argument b. The 24 high-order bits of b are ignored.

所以,將一個int型的變量完整的寫入流中,并不是一個很簡單的問題。讓我們再回到上面這端代碼: 它是連續(xù)四次寫入,每次寫入一個字節(jié)的數(shù)據(jù),這樣一個int型的變量,就被變?yōu)?個字節(jié)寫入流中了。

out.write((v >>> 24) & 0xFF); 這個方法就是上面的寫入較低的8位數(shù)字,這個具體實(shí)現(xiàn)是相應(yīng)的子類提供的。

我們來看看圖解: 一個簡單的與運(yùn)算:可以看出運(yùn)算的結(jié)果是保留了低8位,這個就是 (v>>>24) & 0xFF 運(yùn)算的結(jié)果。

在這里插入圖片描述

那么如何獲取高8位的值呢?這就要使用移位運(yùn)算進(jìn)行操作了:

在這里插入圖片描述

通過進(jìn)行移位操作,就可以獲取每8位的數(shù)據(jù),然后再進(jìn)行按位與 & 運(yùn)算,就可以將一個int型整數(shù)完全的寫入流中了。

代碼演示

代碼

package dragon;

/**
 * 分析這一個方法,目前水平有限,先從最簡單的做起!
 * */

//		   public final void writeInt(int v) throws IOException {
//        out.write((v >>> 24) & 0xFF);
//        out.write((v >>> 16) & 0xFF);
//        out.write((v >>>  8) & 0xFF);
//        out.write((v >>>  0) & 0xFF);
//        incCount(4);
//    }


//上面這段代碼是將一個32位整型,寫入輸出流。
//并且是將32位整型分為4個部分,每次寫入8位。
//這是Java的特性。


public class DataOutputStreamAnalysis {
	public static void main(String[] args) {
		DataOutputStreamAnalysis analysis = new DataOutputStreamAnalysis();
		analysis.analysis(65535);
	}
	
	public void analysis(int number) {
		int number1, number2, number3, number4;  //后面的數(shù)字表示是一個32位整型的第幾個8位。
		number1 = (number >>> 24) & 0xFF;    
		number2 = (number >>> 16) & 0xFF;    
		number3 = (number >>> 8) & 0xFF;
		number4 = (number >>> 0) & 0xFF;
		
		
		
		System.out.println(this.format(Integer.toBinaryString(number))+"  原始數(shù)據(jù)"); 
		System.out.println(this.format(Integer.toBinaryString(number1))+"  原始數(shù)據(jù)第一個8位");
		System.out.println(this.format(Integer.toBinaryString(number2))+"  原始數(shù)據(jù)第二個8位");
		System.out.println(this.format(Integer.toBinaryString(number3))+"  原始數(shù)據(jù)第三個8位");
		System.out.println(this.format(Integer.toBinaryString(number4))+"  原始數(shù)據(jù)第四個8位");
	}
	
	/**
	 * 輸入一個二進(jìn)制字符串,將其格式化,因?yàn)檎褪?
	 * 占32位的,但是轉(zhuǎn)換成的二進(jìn)制字符串,并沒有32位*/
	public String format(String bstr) {
		int len = bstr.length();
		StringBuilder sb = new StringBuilder(35);
		for (int i = 0; i < 32-len; i++) {
			sb.append("0");
		}
		sb.append(bstr);
		sb.insert(8, " ");
		sb.insert(17, " ");
		sb.insert(26, " ");   //前面插入一個字符后,所有字符的索引都變了!
		return sb.toString();
	}
}

結(jié)果

在這里插入圖片描述

說明: 這里沒有考慮負(fù)數(shù)的情況,不過都是一樣的,只是負(fù)數(shù)的表示相對麻煩一點(diǎn)而已。只要理解正數(shù),負(fù)數(shù)也不是什么問題了。

位運(yùn)算的應(yīng)用

1.判斷 int 型變量x是奇書還是偶數(shù)

將變量 x 和 1 進(jìn)行按位與運(yùn)算,如果結(jié)果為 0,則變量x為偶數(shù),否則為奇數(shù)。

if (x & 1 ==0) 
	System.out.println("x是偶數(shù)");
if (x & 1 == 1) 
    System.out.println("x是奇數(shù)");

說明:這個還是很好理解的,因?yàn)榕紨?shù)的最后移位一定是 0。(二進(jìn)制表示)

2.取 int 型變量 x 的第 k 位 將變量 x 右移 k 位,再和1進(jìn)行邏輯與運(yùn)算,結(jié)果即為變量 x 第 k 位的二進(jìn)制值。

表達(dá)式:x >> k & 1 (推薦加上括號,這樣顯得更加清晰明了。)

3.將 int 型變量 x 的第 k 位置 1 將 1 左移 k 位,再和變量 x 進(jìn)行邏輯或運(yùn)算,則將變量 x 的第 k 位置 1,其它位保持不變。

表達(dá)式:x = x | (1 << k)

4.將 int 型變量的第 k 位 清 0 將 1 左移 k 位再取反,將其結(jié)果再和變量 下進(jìn)行邏輯運(yùn)算,則將變量 x 的第 k 位清 0,其它位保持不變。

表達(dá)式位:x = x & ~(1 << k)

5.計算兩個整數(shù)的平均值

表達(dá)式位:(x & y) + ((x ^ y) >> 1)

6.對于大于1 的整數(shù) x,判斷 x 是不是 2 的冪

if (x & (x-1) == 0)
	System.out.println("x是2的次冪");

7.將一個數(shù)乘以 2 的 n 次冪

表達(dá)式:x = x << n

例如:將 x 擴(kuò)大 2 倍:x = x << 1

推薦使用位運(yùn)算的原因:

位運(yùn)算的速度是快于算術(shù)運(yùn)算的,因?yàn)槲贿\(yùn)算需要的指令少,執(zhí)行所需要的時間就少,會顯得很快,但是只有在大量執(zhí)行的情況下才能看出來位運(yùn)算的優(yōu)點(diǎn)。畢竟現(xiàn)在的計算機(jī)已經(jīng)越來越快了。

到此這篇關(guān)于詳解Java的位運(yùn)算的文章就介紹到這了,更多相關(guān)Java位運(yùn)算內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

成武县| 建湖县| 铜陵市| 三穗县| 黔西| 于田县| 周至县| 凯里市| 卫辉市| 南京市| 外汇| 濮阳县| 阳泉市| 连城县| 工布江达县| 九龙县| 鄂尔多斯市| 长治县| 东丽区| 仙游县| 梅州市| 离岛区| 贵德县| 密山市| 宁阳县| 林周县| 眉山市| 米林县| 三亚市| 都昌县| 三台县| 龙江县| 三穗县| 炎陵县| 汉源县| 温州市| 江都市| 吴堡县| 阜宁县| 渭南市| 杭锦后旗|