亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

為什么4-1中的例子補0,不需要&0xff,但是用字節數組byte[i]比較的時候要&0xff

4-1 中的代碼

while((b=in.read())!=-1){
????if(b<=0xf){
????????//補0
????????System.out.print("0");
????}

4-2

byte[]?buf?=?new?byte[20*1024];
int?bytes?=?in.read(buf,0,buf.length);
for?(int?i?=?0;?i?<bytes?;?i++)?{
????if((buf[i]&0xff)<=0xf){
????????//補0
????????System.out.print("0");
}

read方法返回的是一個字節? 這里先假設是一個字節

buf[i]同樣也是字節

都是一個byte和0xf比較,為什么第一個不需要&0xff

我覺得第一個例子也是要&0xff的

今天看的一些資料:

如果read()返回的是byte的話,那就會有負數。而"返回-1意味著結束",這個信息量用byte是無法表達的,所以必須用int。

也就是b=in.read()返回的實際上是一個int型的,如果是這樣的話,byte確實不用0xff

第一個問題似乎有些眉目了,但是如果是這樣的話,那么第二個buf[i]又是怎么回事?

buf[i]從處理上步驟上看需要&0xff,我推測buf[i]在比較之前需要先轉為int型,負數前面全補1,所以為11111111 11111111 1111111 11111111,所以需要手動做0xff處理

正在回答

5 回答

不好意思,是我沒有解釋清楚。這個問題提的好!

首先我們貼出Java的源碼:

public synchronized int read() throws IOException {
  if (pos >= count) {
    fill();
  if (pos >= count)
    return -1;
  }
  return getBufIfOpen()[pos++] & 0xff;

注意返回值,read的返回值雖然是int,但是他是讀取的byte&0xff得到的,而例2中,因為直接是byte,所以老師人為的加上了這一句。

現在問題實際上就變成了為什么不能直接和0x0f比較大小,而要加上& 0xff。以-1即就是11111111自己試一試就知道了,這個之前的回答已經解釋過。

根據我粗淺的理解,Java源碼中& 0xff這一句避免了在讀取-1時函數返回-1而錯誤結束的情況,實際上這時會返回225。

3 回復 有任何疑惑可以回復我~
#1

未卜先知 提問者

非常感謝你的解答,我還是沒習慣看源碼
2016-12-18 回復 有任何疑惑可以回復我~
#2

暮女神

感謝!
2017-03-02 回復 有任何疑惑可以回復我~

我的理解:byte型參與運算時,默認提升為int型,0xff的作用是消除前面24位,轉換為0得到后面8位。read()讀第一個字節時,比如1011 1101,它會提升為int型,前面補0,是整數189。read(buf,0,buf.length)讀取時,假如buf[0]是讀取的第一個字節,byte型的負數,但當轉換為二進制時為:11111111 11111111 11111111 10111101,前面是補1的,為負數,所以用0xff消除前面24個1,轉換為0,得到后八位,是整數189。具體怎么實現,需要學習底層源碼。

1 回復 有任何疑惑可以回復我~

借用我另一個回答,不是很對口,但是可以解釋;

凌晨來回答問題。

首先我們要弄明白,對于一個buf[i], 我們在什么情況下需要在輸出之前補0,什么時候不需要補0.答案很清楚,如果它的高四位都是0,那么我們需要補,否則不需要。那么問題來了,怎么判斷呢?

老師的代碼是用buf[i] <= 0xf,可是代碼結果不正確,會出現錯誤補0,也就是三個數字一起的情況。如果buf[i] == 0xff, 那么按程序是需要補0,因為作為一個byte,0xff實際上等于-1, 那么自然也小于0xf,因為0xf代表15.這就是出錯的問題。

if判定語句改為((buf&oxff)<=oxf)之后,實際上結果就正確了。因為在Java中整數默認是int,也就是4個字節。因為有buf[i] & 0xff, 注意這里0xff 是4個字節的int類型,那么計算之前會把buf[i]自動進行類型轉換,結果也是int類型,所以我們最終的到的結果是24位0加上原先的8位buf[i]。這時候的結果已經絕對是個正數,此時要判斷buf[i]高4位是否有1,就看他和0xf的大小就行了。這里要設計一點補碼的知識,我們還是以buf[i] == 0xff為例:

((buf&oxff)<=oxf)之后的結果是0x000000ff, 顯然是大于0xf,所以沒有補0.

實際上,我們也可以這么判斷:buf[i] & 0xf0 == 0;這樣的結果會保留buf[i]的高四位,其他位都是0,比較容易理解。


0 回復 有任何疑惑可以回復我~
#1

未卜先知 提問者

其實你還是沒回答核心問題,第一個方法,read方法讀到的是一個字節,假設是-1(當然這里用-1來假設不是太好) 第二個方法,buf[i]里面存的也是一個字節,假設讀到的也是-1,這兩個按道理說存的是一樣的東西,為什么一個需要0xff,一個不需要0xff
2016-12-15 回復 有任何疑惑可以回復我~

我覺得都可以,可能只是講解者隨意了

0 回復 有任何疑惑可以回復我~

因為while啊?

0 回復 有任何疑惑可以回復我~

舉報

0/150
提交
取消

為什么4-1中的例子補0,不需要&0xff,但是用字節數組byte[i]比較的時候要&0xff

我要回答 關注問題
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號