欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
java中的有符號,無(wú)符號操作以及DataInputStream

 

參考:Thinking in Java 4版》

java解惑你知多少(一)

       java基本數據類(lèi)型

 

1           無(wú)符號和有符號

計算機中用補碼表示負數,并且有一定的計算方式;另外,用二進(jìn)制的最高位表示符號,0表示正數、1表示負數。這種說(shuō)法本身沒(méi)錯,可是要有一定的解釋?zhuān)蝗凰褪清e的,至少不能解釋?zhuān)瑸槭裁醋址?lèi)型的-1二進(jìn)制表示是“1111 111116進(jìn)制表示為FF,而不是1000 0001。

 

在計算機中,可以區分正負的類(lèi)型,稱(chēng)為有符號類(lèi)型,無(wú)正負的類(lèi)型,稱(chēng)為無(wú)符號類(lèi)型。

 

使用二進(jìn)制中的最高位表示正負

一個(gè)字節為8位,按0開(kāi)始記,那它的最高位就是第7位,2個(gè)字節,最高位就是15位,4個(gè)字節,最高位是31位,不同長(cháng)度的類(lèi)型,最高為業(yè)不同,但總是最左邊那位。

 
 

 

無(wú)符號和有符號數的范圍的區別

無(wú)符號數中,所有的位都用于直接表示該值的大??;有符號數中最高位用于表示正負,所以,正值時(shí),該數的最大值就會(huì )變?。?/span>

無(wú)符號數:1111 1111 值:255=1*2^7+1*2^6+.....=2^n-1

有符號數:0111 1111 值:127

 

同樣一個(gè)字節,無(wú)符號的最大值是255,有符號的最大值是127,下圖是無(wú)符號數和有符號數的范圍:

 

 
 

一個(gè)由符號的數據類(lèi)型的最大值的計算方法完全和無(wú)符號一樣,只不過(guò)它少了一個(gè)最高位,但是在負數范圍內,數值的計算方法不能直接使用前面的公式,在計算機種,負數除了最高位為1以外,還采用補碼的形式,所以在計算前,需要對補碼進(jìn)行還原。

 

10進(jìn)制的計算經(jīng)驗,1表示正1,-1表示和1相對的負值。那么很容易想到在二進(jìn)制中,0000 0001表示正1,則高位為1后:1000 0001應該表示-1,不過(guò)實(shí)際上,計算機中的規定有些相反:

 

可以發(fā)現,1000 0000沒(méi)有拿來(lái)表示-0,而1000 0001也不能拿來(lái)直觀(guān)地表示-1,事實(shí)上,-11111 1111來(lái)表示。從一個(gè)角度來(lái)理解,-1大還是-128大,當然是-1大,-1是最大的負整數,所以,無(wú)論是字符類(lèi)型或整數類(lèi)型,也無(wú)論這個(gè)整數是幾個(gè)字節,從計算結果上來(lái)看也是對的:1111 1111-1=1111 1110,表示-2,這樣一直減下去,當減到只身最高位用于表示符號的1以外,其他低位全為0,就是最小的負值,也就是-128

 
2          

Java基本數據類(lèi)型 

 
 
3          

Java
符號類(lèi)型

 

Java的原始類(lèi)型里沒(méi)有無(wú)符號類(lèi)型,如果需要某個(gè)寬度的無(wú)符號類(lèi)型,可以用>>>,這個(gè)是java的無(wú)符號右移操作符,或者使用下一個(gè)寬度的帶符號類(lèi)型來(lái)模擬,例如,需無(wú)符號的short,就用int來(lái)模擬:

 

1         int toUnsigned(short s) { 

2             return s & 0x0FFFF; 

3         } 

 

 

十進(jìn)制的字面常理只有一個(gè)特性,就是所有的十進(jìn)制字面常量都是正數,如果想寫(xiě)一個(gè)負的十進(jìn)制,則需要在正的十進(jìn)制字面常量前面加上“-”就好了。

 

十六進(jìn)制或者八進(jìn)制的字面常量就不一定是正數或者負數,如果最高位是1,那么就是負數:

1         System.out.println(0x80);//128   

2         //0x81看作是int型,最高位(32)0,所以是正數 

3         System.out.println(0x81);//129   

4         System.out.println(0x8001);//32769 

5         System.out.println(0x70000001);//1879048193   

6         //字面量0x80000001int型,最高位(32)1,所以是負數 

7         System.out.println(0x80000001);//-2147483647 

8         //字面量0x80000001L強制轉為long型,最高位(第64位)為0,所以是正數 

9         System.out.println(0x80000001L);//2147483649 

10     //最小int 

11     System.out.println(0x80000000);//-2147483648 

12     //只要超過(guò)32位,就需要在字面常量后加L強轉long,否則編譯時(shí)出錯 

13     System.out.println(0x8000000000000000L);//-922337203685477

 

4           有符號擴展和無(wú)符號擴展

System.out.println(Long.toHexString(0x100000000L + 0xcafebabe));// cafebabe

結果為什么不是0x1cafebabe?該程序執行的加法是一個(gè)混合類(lèi)型的計算:左操作數是long型,而右操作數是int類(lèi)型。為了執行該計算,Javaint類(lèi)型的數值用拓寬原生類(lèi)型轉換提升為long類(lèi)型,然后對兩個(gè)long類(lèi)型數值相加。因為int是有符號的整數類(lèi)型,所以這個(gè)轉換執行的是符號擴展。


這個(gè)加法的右操作數0xcafebabe32位,將被提升為long類(lèi)型的數值0xffffffffcafebabeL,之后這個(gè)數值加上了左操作0x100000000L。當視為int類(lèi)型時(shí),經(jīng)過(guò)符號擴展之后的右操作數的高32位是-1,而左操作數的第32位是1,兩個(gè)數

值相加得到了0
  0x ffffffffcafebabeL
+0x 0000000100000000L
-----------------------------
 0x 00000000cafebabeL

如果要得到正確的結果0x1cafebabe,則需在第二個(gè)操作數組后加上“L”明確看作是正的long型即可,此時(shí)相加時(shí)拓

展符號位就為0

Java代碼

1         System.out.println(Long.toHexString(0x100000000L + 0xcafebabeL));// 1cafebabe

 

5           窄數字類(lèi)型提升至寬類(lèi)型時(shí)使用符號位擴展還是零擴展

System.out.println((int)(char)(byte)-1);// 65535 

結果為什么是65535而不是-1?

 

窄的整型轉換成較寬的整型時(shí)符號擴展規則:如果最初的數值類(lèi)型是有符號的,那么就執行符號擴展(即如果符號位為1,則擴展為1,如果為零,則擴展為0);如果它是char,那么不管它將要被提升成什么類(lèi)型,都執行零擴展。

 

了解上面的規則后,我們再來(lái)看看迷題:因為byte是有符號的類(lèi)型,所以在將byte數值-1(二進(jìn)制為:11111111)提升到char時(shí),會(huì )發(fā)生符號位擴展,又符號位為1,所以就補8個(gè)1,最后為16個(gè)1;然后從charint的提升時(shí),由于是char型提升到其他類(lèi)型,所以采用零擴展而不是符號擴展,結果int數值就成了65535。

 

如果將一個(gè)char數值c轉型為一個(gè)寬度更寬的類(lèi)型時(shí),只是以零來(lái)擴展,但如果清晰表達以零擴展的意圖,則可以考慮

使用一個(gè)位掩碼:

Java代碼

1         int i = c & 0xffff;//實(shí)質(zhì)上等同于:int i = c ; 

說(shuō)明:

至于0xff,這屬于java的字面常量,他已經(jīng)是int了,ff表示為11111111,java對這種字面常量,不把他前面的1看做符號位,雖然也是有符號擴展,但是,擴展成的是00...ff.

數字字面常量的類(lèi)型都是int型,而不管他們是幾進(jìn)制,所以“2147483648”、“0x180000000(十六進(jìn)制,共33位,所以超過(guò)了整數的取值范圍)字面常量是錯誤的,編譯時(shí)會(huì )報超過(guò)int的取值范圍了,所以要確定以long來(lái)表示“2147483648L”、“0x180000000L”。

 

 System.out.println(0x80000001);//-2147483647 ,已經(jīng)是32位,最高位是符號位

System.out.println(0xcafebabe);//-889275714

System.out.println(0xffff);     //65535 int32位的,最高位已經(jīng)是0,相當于0X0000ffff

System.out.println(0xff);       //255

 

如果將一個(gè)char數值c轉型為一個(gè)寬度更寬的整型,并且希望有符號擴展,那么就先將char轉型為一個(gè)short,它與char上個(gè)具有同樣的寬度,但是它是有符號的:

2         int i = (short)c; 

 

如果將一個(gè)byte數值b轉型為一個(gè)char,并且不希望有符號擴展,那么必須使用一個(gè)位掩碼來(lái)限制它:

3         char c = (char)(b & 0xff);// char c = (char) b;為有符號擴展 

 

((byte)0x90 == 0x90)?

 

答案是不等的,盡管外表看起來(lái)是成立的,但是它卻等于false。為了比較byte數值(byte)0x90int數值0x90,Java

通過(guò)拓寬原生類(lèi)型將byte提升為int,然后比較這兩個(gè)int數值。因為byte是一個(gè)有符號類(lèi)型,所以這個(gè)轉換執行的是符號擴展,將負的byte數值提升為了在數字上相等的int值(10010000?111111111111111111111111 10010000)。在本例中,該轉換將(byte)0x90提升為int數值-112,它不等于int數值的0x90,即+144。


解決辦法:使用一個(gè)屏蔽碼來(lái)消除符號擴展的影響,從而將byte轉型為int。

Java代碼

1         ((byte)0x90 & 0xff)== 0x90 

 

6           Javabyte轉換int時(shí)與0xff進(jìn)行與運算的原因

javabyte轉換int時(shí)為何與0xff進(jìn)行與運算

在剖析該問(wèn)題前請看如下代碼
 public static String bytes2HexString(byte[] b) {
  String ret = "";
  for (int i = 0; i < b.length; i++) {
   String hex = Integer.toHexString(b[i] & 0xFF);
   if (hex.length() == 1) {
    hex = '0' + hex;
   }
   ret += hex.toUpperCase();
  }
  return ret;
 }
上面是將byte[]轉化十六進(jìn)制的字符串,注意這里b[i] & 0xFF將一個(gè)byte 0xFF進(jìn)行了與運算,然后使用Integer.toHexString取得了十六進(jìn)制字符串,可以看出
b[i] & 0xFF
運算后得出的仍然是個(gè)int,那么為何要和 0xFF進(jìn)行與運算呢?直接 Integer.toHexString(b[i]);,byte強轉為int不行嗎?答案是不行的.

其原因在于:
1.byte
的大小為8bitsint的大小為32bits
2.java
的二進(jìn)制采用的是補碼形式

在這里先溫習下計算機基礎理論

byte是一個(gè)字節保存的,有8個(gè)位,即8個(gè)0、1。
8
位的第一個(gè)位是符號位,
也就是說(shuō)0000 0001代表的是數字1
1000 0000
代表的就是-1
所以正數最大位0111 1111,也就是數字127
負數最大為1111 1111,也就是數字-128

上面說(shuō)的是二進(jìn)制原碼,但是在java中采用的是補碼的形式,下面介紹下什么是補碼

Integer.toHexString的參數是int,如果不進(jìn)行&0xff,那么當一個(gè)byte會(huì )轉換成int時(shí),由于int32位,而byte只有8位這時(shí)會(huì )進(jìn)行補位,例如補碼11111111的十進(jìn)制數為-1轉換為int時(shí)變?yōu)?/span>11111111111111111111111111111111好多1啊,呵呵!即0xffffffff但是這個(gè)數是不對的,這種補位就會(huì )造成誤差。和0xff相與后,高24比特就會(huì )被清0了,結果就對了。

 

補碼是有符號數,所以從8位變?yōu)?/span>int需要有符號擴展,變?yōu)?/span>11111111111111111111111111111111(最終的值為-1)。

至于0xff,這屬于java的字面常量,他已經(jīng)是int了,ff表示為11111111,java對這種字面常量,不把他前面的1看做符號位,雖然也是有符號擴展,但是,擴展成的是00...ff.

一般在有些編譯器重,寫(xiě)ff,會(huì )把第一位1認為是符號位,所以可以這么寫(xiě):0x0ff

 

7          DataInputStream

 

DataInputStream in = new DataInputStream(

                                new BufferedInputStream(fileInputStream));

 

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
JAVA的位操作符
用Java實(shí)現JVM第三章《解析class文件》附[classReader拆解]
java位運算
Java 位運算符
大數據Java基礎——移位運算的真實(shí)剖析 (二)
Java 與無(wú)符號那些事兒
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久