關於JAVA中Byte數據類型二進制賦值運算報錯問題


      自從JDK7更新之后,新增了二進制變量的表示,支持將整數類型用二進制來表示,用0b開頭;

例如: byte b= (byte) 0b1000_0001;

            short s = (short) 0b1000_0000_0000_0001;

      新手在這個時候會遇到一個問題,為啥byte b=0b100_00001會報錯(cannot convert from int to byte)

而short b=0b100_00001又不會呢?既然java底層默認0b100_00001是int類型,為什么short可以呢?

有的人說是byte是字節數據類型,short是短整數據類型,個人認為不太准確。所以我們在做個試驗:

 

試驗1:short b=0b100_00001;//正常賦值;

             short s=0b1000_0000_0000_0001;//系統報錯(cannot convert from int to byte);

 

      這個結果出來想必大家都有些眉目了,在二進制中最高位被定義為符號位,byte共有8個比特位,我們給它

0b0000_0001時,最高位0系統無法判斷是 實際數值 還是 符號位數值 。如果我們加上(byte),則系統認為

此時的0是符號位,可以賦值;如果沒有加(byte),則認為是實際數值,然而byte類型只有8個比特位,無位置

表示符號位,因此溢出報錯。

試驗2:byte b=0b0000_0001;// 正常賦值

             byte b=0b1000_0000;//報錯

       再次印證了上面的推理,默認最高位是實際數值,超出位寬報錯。

-----------------------------------------------------------------黃金分割線---------------------------------------------------------------------

問題2:

       byte a=(byte)0b1111_1111+0b0000_0001;  ---> 0 //運行結果為0

     有人解釋道0b0000_0001為int類型,而(byte)0b1111_1111為byte類型,運算時會轉為int類型運算,即為:

                                       0000_0000_0000_0000_0000_0000_1111_1111

                                                                             +   

                                       0000_0000_0000_0000_0000_0000_0000_0001

                                                                             ||

                                       0000_0000_0000_0000_0000_0001_0000_0000

                                                                             || 轉為byte類型,直接截取后8位

                                                                     0000_0000  =  0

那么又有人問了:

                        int a=(byte)0b1111_1111+0b0000_0001; 0  //運行結果同樣為0,為什么不是256

            按照上面的意思被賦值變量a屬於int類型,既然是按照int類型運算,結果就不用轉換了嘛,直接賦值不就行啦?

我們在看幾組試驗:

               1 、  byte a=(byte)0b0000_0001+0b1111_1111; -->報錯 //cannot convert from int to byte

                        int a=(byte)0b0000_0001+0b1111_1111; -->256 正常賦值 

 

              2 、   byte a=(byte)0b1111_1111+(byte)0b0000_0001; --> 0

                        int a=(byte)0b1111_1111+(byte)0b0000_0001; --> 0

 

              3、    byte a=(byte)(0b1111_1111+0b0000_0001); --> 0

                        int a=(byte)(0b1111_1111+0b0000_0001); --> 0

 

              4、    int a=0b1111_1111+0b0000_0001; --> 256

         第一組報錯從第一個問題可以推出,0b1111_1111超出了等號左邊的byte類型范圍,所以才會報錯。

我們有三種推斷:

        第一、如果是都轉為byte類型進行運算,那會考慮到符號位,多余正溢出,超出位寬自然舍棄,相加結果應為0b1000_0000,結果應為-128才對

顯然結果不是這樣的,因此這種推斷錯誤;

       第二、如果是都轉為int類型進行運算,然后把值賦值給等號左邊,這種推論試驗2中int a=0,說不通,因此這種推斷錯誤;

       第三、運算按照java直接值得規則,數值類型進行算數運算時,所有參與算數運算的數都會自動轉換為參與運算的最大類型,得到的值也是該類型

我們一一驗證補碼運算的結果{(byte)0b1111_1111對應的原碼為1000_0001即為-1,而0000_0001位1,相加結果為0},以上問題都可以推理出來,

因此,第三種推論是正確的,打完收工。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM