為什么4-1中的例子補(bǔ)0,不需要&0xff,但是用字節(jié)數(shù)組byte[i]比較的時候要&0xff
4-1 中的代碼
while((b=in.read())!=-1){ ????if(b<=0xf){ ????????//補(bǔ)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){ ????????//補(bǔ)0 ????????System.out.print("0"); }
read方法返回的是一個字節(jié)? 這里先假設(shè)是一個字節(jié)
buf[i]同樣也是字節(jié)
都是一個byte和0xf比較,為什么第一個不需要&0xff
我覺得第一個例子也是要&0xff的
今天看的一些資料:
如果read()返回的是byte的話,那就會有負(fù)數(shù)。而"返回-1意味著結(jié)束",這個信息量用byte是無法表達(dá)的,所以必須用int。
也就是b=in.read()返回的實(shí)際上是一個int型的,如果是這樣的話,byte確實(shí)不用0xff
第一個問題似乎有些眉目了,但是如果是這樣的話,那么第二個buf[i]又是怎么回事?
buf[i]從處理上步驟上看需要&0xff,我推測buf[i]在比較之前需要先轉(zhuǎn)為int型,負(fù)數(shù)前面全補(bǔ)1,所以為11111111 11111111 1111111 11111111,所以需要手動做0xff處理
2016-12-18
不好意思,是我沒有解釋清楚。這個問題提的好!
首先我們貼出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中,因?yàn)橹苯邮莃yte,所以老師人為的加上了這一句。
現(xiàn)在問題實(shí)際上就變成了為什么不能直接和0x0f比較大小,而要加上& 0xff。以-1即就是11111111自己試一試就知道了,這個之前的回答已經(jīng)解釋過。
根據(jù)我粗淺的理解,Java源碼中& 0xff這一句避免了在讀取-1時函數(shù)返回-1而錯誤結(jié)束的情況,實(shí)際上這時會返回225。
2017-02-06
我的理解:byte型參與運(yùn)算時,默認(rèn)提升為int型,0xff的作用是消除前面24位,轉(zhuǎn)換為0得到后面8位。read()讀第一個字節(jié)時,比如1011 1101,它會提升為int型,前面補(bǔ)0,是整數(shù)189。read(buf,0,buf.length)讀取時,假如buf[0]是讀取的第一個字節(jié),byte型的負(fù)數(shù),但當(dāng)轉(zhuǎn)換為二進(jìn)制時為:11111111 11111111 11111111 10111101,前面是補(bǔ)1的,為負(fù)數(shù),所以用0xff消除前面24個1,轉(zhuǎn)換為0,得到后八位,是整數(shù)189。具體怎么實(shí)現(xiàn),需要學(xué)習(xí)底層源碼。
2016-12-14
借用我另一個回答,不是很對口,但是可以解釋;
凌晨來回答問題。
首先我們要弄明白,對于一個buf[i], 我們在什么情況下需要在輸出之前補(bǔ)0,什么時候不需要補(bǔ)0.答案很清楚,如果它的高四位都是0,那么我們需要補(bǔ),否則不需要。那么問題來了,怎么判斷呢?
老師的代碼是用buf[i] <= 0xf,可是代碼結(jié)果不正確,會出現(xiàn)錯誤補(bǔ)0,也就是三個數(shù)字一起的情況。如果buf[i] == 0xff, 那么按程序是需要補(bǔ)0,因?yàn)樽鳛橐粋€byte,0xff實(shí)際上等于-1, 那么自然也小于0xf,因?yàn)?xf代表15.這就是出錯的問題。
if判定語句改為((buf&oxff)<=oxf)之后,實(shí)際上結(jié)果就正確了。因?yàn)樵贘ava中整數(shù)默認(rèn)是int,也就是4個字節(jié)。因?yàn)橛衎uf[i] & 0xff, 注意這里0xff 是4個字節(jié)的int類型,那么計(jì)算之前會把buf[i]自動進(jìn)行類型轉(zhuǎn)換,結(jié)果也是int類型,所以我們最終的到的結(jié)果是24位0加上原先的8位buf[i]。這時候的結(jié)果已經(jīng)絕對是個正數(shù),此時要判斷buf[i]高4位是否有1,就看他和0xf的大小就行了。這里要設(shè)計(jì)一點(diǎn)補(bǔ)碼的知識,我們還是以buf[i] == 0xff為例:
((buf&oxff)<=oxf)之后的結(jié)果是0x000000ff, 顯然是大于0xf,所以沒有補(bǔ)0.
實(shí)際上,我們也可以這么判斷:buf[i] & 0xf0 == 0;這樣的結(jié)果會保留buf[i]的高四位,其他位都是0,比較容易理解。
2016-12-03
我覺得都可以,可能只是講解者隨意了
2016-12-03
因?yàn)閣hile啊?