java byte 值为0xff_Java byte转int为什么要用&0xff

我们查看很多源码的时候都会看到在byte转int的时候会&0xff,为什么会有这个操作呢。

byte[127]转int

看下面代码:

byte[] b = new byte[1];

b[0] = 127;

// 127

System.out.print(b[0]);

// 127

System.out.print(b[0] & 0xff);

两者的输出都为127,看不出有什么问题。

byte[-127]转int

我们将数值改为-127时

byte[] b = new byte[1];

b[0] = -127;

// -127

System.out.print(b[0]);

// 129

System.out.print(b[0] & 0xff);

为什么&0xff反而数值变得奇怪了呢。

数据扩展

众所周知计算机内二进制都是以补码形式存储的。byte类型的长度为8bit,而int类型为32bit。

在将低精度转成高精度数据类型,有两种扩展方案。

(1)补零扩展,能够保证二进制存储的一致性,但不能保证十进制值不变

(2)符号位扩展,能够保证十进制值不变,但不能保证二进制存储的一致性

正数

对于正数来说这两种是一样的。当b[0] 为127的时候,b[0] 补码为01111111

1.补零扩展以后为00000000 00000000 00000000 01111111

2.符号位扩展以后也为00000000 00000000 00000000 01111111

负数

对于负数来说就不一样了。当b[0] 为-127的时候,b[0] 补码为10000001

1.补零扩展以后为00000000 00000000 00000000 10000001

2.符号位扩展以后为11111111 11111111 11111111 10000001

tips:Java对于有符号的扩展,使用的是符号位扩展来保证十进制的值不变。

即扩展以后为11111111 11111111 11111111 10000001,其原码就为10000000 00000000 00000000 01111111,其十进制值为-127

但是其二进制表示发生了变化补码从10000001变为了11111111 11111111 11111111 10000001。

使用&0xff

所以很多时候为了保证低八位的二进制不变,使用&0xff

`11111111 11111111 11111111 10000001 & 0xff =

11111111 11111111 11111111 10000001 & 11111111 =

00000000 00000000 00000000 10000001` 但是十进制变成了 129

实例 byte[]转为int

我们用实例看一下&0xff对转换时的影响,如下所示我们期望得到的int00000000 00000000 00000001 10000001十进制为385,如果不加&0xff则会得到-127。

tips:java 中对byte的所有运算操作均会是首先将byte转化为int, 再行运算

byte[] bs = new byte[4];

// 10000001

bs[0] = (byte) -127;

// 00000001

bs[1] = (byte) 1;

// 00000000

bs[2] = (byte) 0;

// 00000000

bs[3] = (byte)0;

// (bs[0]&0xff):00000000 00000000 00000000 10000001 或

// (bs[1]&0xff):00000000 00000000 00000001 00000000

// -----------------------------------

// 00000000 00000000 00000001 10000001 或

// (bs[2]&0xff):00000000 00000000 00000000 00000000

// -----------------------------------

// 00000000 00000000 00000001 10000001 或

// (bs[3]&0xff):00000000 00000000 00000000 00000000

// -----------------------------------

// 00000000 00000000 00000001 10000001 正数 = 256+128+1=385

int i = (bs[0]&0xff) | ((bs[1]& 0xff)<<8)| ((bs[2]& 0xff)<<16) | ((bs[3]& 0xff)<<24);

// bs[0]:11111111 11111111 11111111 10000001 或

// bs[1]:00000000 00000000 00000001 00000000

// -----------------------------------

// 11111111 11111111 11111111 10000001 或

// bs[2]:00000000 00000000 00000000 00000000

// -----------------------------------

// 11111111 11111111 11111111 10000001 或

// bs[3]:00000000 00000000 00000000 00000000

// -----------------------------------

// 这里得到的是补码(负数),需要转成原码

// 11111111 11111111 11111111 10000001 - 1

// 11111111 11111111 11111111 10000000 取反

// 10000000 00000000 00000000 01111111 = -127

int k = (bs[0]) | ((bs[1])<<8)| ((bs[2])<<16) | ((bs[3])<<24);

// 385

System.out.print(i);

// -127

System.out.print(k);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值