问题描述:

在文件流读取十六进制文件时,经常需要将某些字节读出来解析成表示大小的int数据,在此转化过程中可能会出现负数,好的解决方法是将byte[i]和0xFF进行与运算,因为byte为8bit,而int是32bit,故而在转化前需将高24位置零,这样就不会出现补码导致的转换错误。

在剖析该问题前请看如下代码
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 0000代表的就是-1
所以正数最大位0111 1111,也就是数字127
负数最大为1111 1111,也就是数字-128

上面说的是二进制原码,但是在java中采用的是补码的形式,下面介绍下什么是补码

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,于是结果总是我们想要的。

byte转int出现负数的情况相关推荐

  1. 负数byte转为int

    /*** byte转int(考虑到byte可能会有超出范围的情况)* @param b* @return*/public static Integer byteToInteger(Byte b){re ...

  2. byte转换int时为何与0xff进行与运算

    2019独角兽企业重金招聘Python工程师标准>>> ava中byte转换int时为何与0xff进行与运算 在剖析该问题前请看如下代码 public static String b ...

  3. byte与或运算 java_java中byte转换int时为何与0xff进行与运算

    本文总结了java中byte转换int时总是与0xff进行与运算的原因. 在剖析该问题前请看如下代码: public static String bytes2HexString(byte[] b) { ...

  4. java将一个整数按字节输出_在java中的整数类型有四种,分别是 byte  short int long 其中byte只有一个字节 0或1,在此不详细讲解。其他的三种类型如下:1、...

    在java中的整数类型有四种,分别是 byte  short int long 其中byte只有一个字节 0或1,在此不详细讲解. 其他的三种类型如下: 1. 基本类型:short 二进制位数:16 ...

  5. java byte转int 互相转换原理详解

    转自:https://blog.csdn.net/wojiuai2093/article/details/50779879 int i = 0;   i += ((b[0] & 0xff) & ...

  6. Java高低位和byte转int

    最近研究I/O流,发现read()方法返回的是int类型,原来是将一个byte读入到一个int,有效的数据只占据int型变量的最低8位.在正常情况下这个int型的变量永远都不可能是负数. 什么是高低位 ...

  7. 基于java的InputStream.read(byte[] b,int off,int len)算法学习!

    public int read(byte[] b,int off,int len)throws IOException 将输入流中最多 len 个数据字节读入字节数组.尝试读取多达 len 字节,但可 ...

  8. JAVA实体类不要使用基本类型,基本类型包含byte、int、short、long、float、double、char、boolean...

    由于JAVA的基本类型会有默认值,例如当某个类中存在private  int age;字段时,创建这个类时,age会有默认值0.当使用age属性时,它总会有值.因此在某些情况下,便无法实现age为nu ...

  9. java byte 和 int 转换

    一个byte占8位,一个int占32位. int 转byte时,需要&0xff,去掉前面的24位.因此当int是正数时,转出的byte可能是负数 byte转int时,需要&0xff,补 ...

最新文章

  1. ThunderGBM:快成一道闪电的梯度提升决策树
  2. 一文看懂中国MEMS传感器产业链
  3. 时讯无线为你提供快速的上网设备
  4. UITabelView使用流程
  5. 2.3 利用正规化解决过拟合问题-机器学习笔记-斯坦福吴恩达教授
  6. icu入院宣教流程图_ICU患者及家属的健康教育PPT.ppt
  7. Flask Web中的db.relationship()
  8. ajax请求整理(一) 2021.05.12
  9. linux 7 postconf,postconf 命令常用参数
  10. 从 200 多篇顶会论文看预训练语言模型研究进展
  11. Python培训班怎么选?
  12. [转]easyui常用控件及样式收藏
  13. 单元测试框架TestableMock快速入门(三):校验Mock调用
  14. WPE教程 传奇神秘商店外挂制作
  15. 大学计算机基础字母缩写大全,大学计算机基础缩写词.pdf
  16. 使用LR11过程中遇到的一些问题汇总
  17. 巨人肩膀上的迁移学习(2)---图像回归
  18. linux内核函数之 blk_plug
  19. 数字的ASCII码值转为大写字母
  20. 访问学者美国访学必须知道十大注意事项

热门文章

  1. html过去手机唯一标识,H5能获取到手机设备ID或者手机浏览器唯一识别码吗
  2. iOS学习之非代码获取iPhone型号及其他信息
  3. 数据库原理-多值依赖
  4. 数字麦克风PDM信号采集与STM32 I2S接口应用(二)
  5. Deformable ConvNets v2 Pytorch版源码讲解_2
  6. java实现导入word模板导入试题
  7. Windows10中SwitchyOmega安装及部分异常处理
  8. Unity UGUI 的RectTransform参数的设置
  9. Java编程思想 第二十章 注解
  10. 今晚直播!池建强、二爷邱岳、左耳朵耗子、朱赟的技术夜话