zoukankan      html  css  js  c++  java
  • java中byte转换int时为何与0xff进行与运算

    本文总结了java中byte转换int时总是与0xff进行与运算的原因。

    在剖析该问题前请看如下代码:

    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[]转化十六进制的字符串,注意这里b[ i ] & 0xFF将一个byte和 0xFF进行了与运算,然后使用Integer.toHexString取得了十六进制字符串,可以看出:b[ i ] & 0xFF 运算后得出的仍然是个int,那么为何要和 0xFF 进行与运算呢?直接 Integer.toHexString(b[ i ]);,将 byte 强转为 int 不行吗?答案是不行的。

    其原因在于:
    1.byte的大小为 8bits 而 int 的大小为 32bits ;
    2.java的二进制采用的是补码形式 ;

    在这里先温习下计算机基础理论:

    byte是一个字节保存的,有8个位,即8个0、1。
    8位的第一个位是符号位,也就是说0000 0001代表的是数字1 ,1000 0001代表的就是-1 。
    所以正数最大位0111 1111,也就是数字127;负数最大为1111 1111,也就是数字-128 。

    上面说的是二进制原码,但是在java中采用的是补码的形式,下面介绍下什么是补码(补码就是原码按位取反再加1,下边的解释有些抽象。):

    1、
    一个数如果是正,则它的反码与原码相同;
    一个数如果是负,则符号位为1,其余各位是对原码取反;

    2、:利用溢出,我们可以将减法变成加法
    对于十进制数,从9得到5可用减法:
    9-4=5 因为4+6=10,我们可以将6作为4的补数
    改写为加法:
    9+6=15(去掉高位1,也就是减10)得到5.

    对于十六进制数,从c到5可用减法:
    c-7=5 因为7+9=16 将9作为7的补数
    改写为加法:
    c+9=15(去掉高位1,也就是减16)得到5.

    在计算机中,如果我们用1个字节表示一个数,一个字节有8位,超过8位就进1,在内存中情况为(100000000),进位1被丢弃。

    ⑴一个数为正,则它的原码、反码、补码相同
    ⑵一个数为负,则符号位为1,其余各位是对原码取反,然后整个数加1

    - 1的原码为                10000001
    - 1的反码为                11111110
                                               + 1
    - 1的补码为                11111111

    0的原码为                 00000000
    0的反码为                 11111111(正零和负零的反码相同)
                                               +1
    0的补码为               100000000(舍掉打头的1,正零和负零的补码相同)

    Integer.toHexString的参数是int,如果不进行&0xff,那么当一个byte会转换成int时,由于int是32位,而byte只有8位这时会进行补位,例如补码11111111的十进制数为 -1 ,转换为int时变为 11111111111111111111111111111111,好多1啊,呵呵!即 0xffffffff,但是这个数是不对的,这种补位就会造成误差。

    和0xff相与后,高24比特就会被清0了,结果就对了。

    重要信息:

    Java中的一个byte,其范围是-128~127的,而Integer.toHexString的参数本来是int,如果不进行&0xff,那么当一个byte会转换成int时,对于负数,会做位扩展,举例来说,一个byte的-1(即0xff),会被转换成int的-1(即0xffffffff),那么转化出的结果就不是我们想要的了。

    而0xff默认是整形,所以,一个byte跟0xff相与会先将那个byte转化成整形运算,这样,结果中的高的24个比特就总会被清0,于是结果总是我们想要的。

  • 相关阅读:
    bzoj2733 永无乡 平衡树按秩合并
    bzoj2752 高速公路 线段树
    bzoj1052 覆盖问题 二分答案 dfs
    bzoj1584 打扫卫生 dp
    bzoj1854 游戏 二分图
    bzoj3316 JC loves Mkk 二分答案 单调队列
    bzoj3643 Phi的反函数 数学 搜索
    有一种恐怖,叫大爆搜
    BZOJ3566 概率充电器 概率dp
    一些奇奇怪怪的过题思路
  • 原文地址:https://www.cnblogs.com/dailidong/p/7571190.html
Copyright © 2011-2022 走看看