zoukankan      html  css  js  c++  java
  • byte[i] & 0xFF原因(byte为什么要与上0xff?)

    转载:byte[i] & 0xFF原因

     

    无意间发现了一段难以理解的代码

    复制代码
         byte[] bs = digest.digest(origin.getBytes(Charset.forName(charsetName))) ;  
              
            for (int i = 0; i < bs.length; i++) {  
                int c = bs[i] & 0xFF ;
                if(c < 16){ 
    
                    sb.append("0");  
                }  
                sb.append(Integer.toHexString(c)) ;  
            }  
            return sb.toString() ;  
    复制代码

    bs是由一段字符串经过MD5加密后,输出的byte数组。起初难以理解为什么在接下来的循环中要将bs[i]&oxFF再复制给int类型呢?

    bs[i]是8位二进制,0xFF转化成8位二进制就是11111111,那么bs[i]&0xFF不是还是bs[i]本身吗?有意思吗?

    后来又写了一个demo

    复制代码
    package jvmProject;
    
    public class Test {
    
        public static void main(String[] args) {
            byte[] a = new byte[10];
            a[0]= -127;
            System.out.println(a[0]);
            int c = a[0]&0xff;
            System.out.println(c);
        }
    }
    复制代码

    先打印a[0],在打印a[0]&0xff后的值,本来想结果应该都是-127.

    但是结果真是出人意料啊!

    -127

    129

    到底是什么原因呢?&0xff反而不对了。

    真的是不懂啊,后来往补码那个方向想了想。

    在学计算机原理的时候,了解到计算机内的存储都是利用二进制的补码进行存储的

    原码反码补码这三个概念

    对于正数(00000001)原码来说,首位表示符号位,反码 补码都是本身

    对于负数(100000001)原码来说,反码是对原码除了符号位之外作取反运算即(111111110),补码是对反码作+1运算即(111111111)

    概念就这么简单。

    当将-127赋值给a[0]时候,a[0]作为一个byte类型,其计算机存储的补码是10000001(8位)。

    将a[0] 作为int类型向控制台输出的时候,jvm作了一个补位的处理,因为int类型是32位所以补位后的补码就是1111111111111111111111111 10000001(32位),这个32位二进制补码表示的也是-127.

    发现没有,虽然byte->int计算机背后存储的二进制补码由10000001(8位)转化成了1111111111111111111111111 10000001(32位)很显然这两个补码表示的十进制数字依然是相同的。

    但是做byte->int的转化 所有时候都只是为了保持 十进制的一致性吗?

    不一定吧?好比拿到的文件流转成byte数组,难道我们关心的是byte数组的十进制的值是多少吗?我们关心的是其背后二进制存储的补码吧

    所以大家应该能猜到为什么byte类型的数字要&0xff再赋值给int类型,其本质原因就是想保持二进制补码的一致性。

    当byte要转化为int的时候,高的24位必然会补1,这样,其二进制补码其实已经不一致了,&0xff可以将高的24位置为0,低8位保持原样。这样做的目的就是为了保证二进制数据的一致性。

    当然拉,保证了二进制数据性的同时,如果二进制被当作byte和int来解读,其10进制的值必然是不同的,因为符号位位置已经发生了变化。

    象例2中,int c = a[0]&0xff;  a[0]&0xff=1111111111111111111111111 10000001&11111111=000000000000000000000000 10000001 ,这个值算一下就是129,

    所以c的输出的值就是129。有人问为什么上面的式子中a[0]不是8位而是32位,因为当系统检测到byte可能会转化成int或者说byte与int类型进行运算的时候,就会将byte的内存空间高位补1(也就是按符号位补位)扩充到32位,再参与运算。上面的0xff其实是int类型的字面量值,所以可以说byte与int进行运算。

  • 相关阅读:
    宿主机无法访问CentOS7上Jenkins服务的解决办法
    415. Add Strings
    367. Valid Perfect Square
    326. Power of Three
    258. Add Digits
    231. Power of Two
    204. Count Primes
    202. Happy Number
    172. Factorial Trailing Zeroes
    171. Excel Sheet Column Number
  • 原文地址:https://www.cnblogs.com/originate918/p/6378005.html
Copyright © 2011-2022 走看看