int和byte数组相互转换详解

ops/2024/9/24 13:33:40/

转换之前我们需要了解各种进制之间的关系,不太了解的可以先看下计算机组成原理和体系 这篇文章

byte

byte是字节的意思,一个字节等于8位,范围是 0000 0000 ~ 1111 1111(十六进制:0x0~0xff),总共包含256个数。
有符号的byte表示的范围为:-128~127
无符号的byte表示的范围为:0~255

java中默认的是有符号的byte,当我们需要与硬件交互时,需要转换为无符号的byte。

一、int转byte数组

1、当value小于等于255时,转换为1个字节,1个字节能表示无符号的范围为0 ~ 2 8 2^{8} 28-1,即0~255

例如:
int value = 246 转换成二进制为 1111 0110

( 246 ) 10 (246)_{10} (246)10 ( 1111 0110 ) 2 (1111\ 0110)_2 (1111 0110)2

转换成二进制为8位,占用1个字节

int value =246
byte[] bytes= new byte[1];
bytes[0] =(byte) (value & 0xFF);

bytes[0]

(byte) (value & 0xFF):这是一个与操作,0xFF是十六进制,转换成二进制为:1111 1111,转换成十进制为:255,当value和0xFF按位与运算时,得到的是value的最后8位(低8位),其余高位将被清零。这样做可以确保结果只包含原始数值的低8位,模拟出无符号整数的行为。

bytes[0]的二进制就为:1111 0110,转换成十六进制为:0xF6

bytes发送到硬件设备,硬件设备接收到的就是0xF6

2、当value大于255时,转换为2个字节,2个字节能表示无符号的范围为0 ~ 2 16 2^{16} 216-1,即0~65535

例如:
int value = 3658,转换成二进制为:1110 0100 1010

( 3658 ) 10 (3658)_{10} (3658)10 ( 1110 0100 1010 ) 2 (1110\ 0100\ 1010)_2 (1110 0100 1010)2

转换成二进制超过8位,占用16位,占用2个字节

int value =3658
byte[] bytes= new byte[2];
bytes[0] =(byte) ((value >> 8) & 0xFF);
bytes[1] =(byte) (value & 0xFF);

bytes[0]

(byte) ((value >> 8) & 0xFF):>>是右移操作,(value >> 8) 是先将value的所有位向右移动8位,移动后的左边(高位)会填充0(因为是无符号右移)。
( 3658 ) 10 (3658)_{10} (3658)10 ( 1110 0100 1010 ) 2 (1110\ 0100\ 1010)_2 (1110 0100 1010)2,(3658 >> 8)得到的是 ( 0000 0000 1110 ) 2 (0000\ 0000\ 1110)_2 (0000 0000 1110)2

& 0xFF:是按位与运算,得到最后8位, ( 0000 0000 1110 ) 2 (0000\ 0000\ 1110)_2 (0000 0000 1110)2 & 0xFF 得到的是 ( 0000 1110 ) 2 (0000\ 1110)_2 (0000 1110)2

所以bytes[0]的二进制值为:0000 1110,转换成十六进制为:0x0E

bytes[1]

(byte) (value & 0xFF) :是按位与运算,得到最后8位, ( 1110 0100 1010 ) 2 (1110\ 0100\ 1010)_2 (1110 0100 1010)2 & 0xFF得到的是 ( 0100 1010 ) 2 (0100\ 1010)_2 (0100 1010)2

所以bytes[1]的二进制值为:0100 1010,转换成十六进制为:0x4A

bytes发送到硬件设备,硬件设备接收到的就是0x0E4A

3、当value大于65535时,转换为3个字节,3个字节能表示无符号的范围为0 ~ 2 24 2^{24} 224-1,即0~16777215

例如:
int value = 5623658,转换成二进制为:0101 0101 1100 1111 0110 1010

( 5623658 ) 10 (5623658)_{10} (5623658)10 ( 0101 0101 1100 1111 0110 1010 ) 2 (0101\ 0101\ 1100\ 1111\ 0110\ 1010)_2 (0101 0101 1100 1111 0110 1010)2

转换成二进制超过16位,占用24位,占用3个字节

int value =5623658
byte[] bytes= new byte[3];
bytes[0] =(byte) ((value >> 16) & 0xFF);
bytes[1] =(byte) ((value >> 8) & 0xFF);
bytes[2] =(byte) (value & 0xFF);

bytes[0]

(byte) ((value >> 16) & 0xFF):>>是右移操作,(value >> 16) 是先将value的所有位向右移动16位,移动后的左边(高位)会填充0(因为是无符号右移)。
( 5623658 ) 10 (5623658)_{10} (5623658)10 ( 0101 0101 1100 1111 0110 1010 ) 2 (0101\ 0101\ 1100\ 1111\ 0110\ 1010)_2 (0101 0101 1100 1111 0110 1010)2,(5623658>> 16)得到的是 ( 0000 0000 0000 0000 0101 0101 ) 2 (0000\ 0000\ 0000\ 0000\ 0101\ 0101)_2 (0000 0000 0000 0000 0101 0101)2

& 0xFF:是按位与运算,得到最后8位, ( 0000 0000 0000 0000 0101 0101 ) 2 (0000\ 0000\ 0000\ 0000\ 0101\ 0101)_2 (0000 0000 0000 0000 0101 0101)2& 0xFF 得到的是 ( 0101 0101 ) 2 (0101\ 0101)_2 (0101 0101)2

所以bytes[0]的二进制值为:0101 0101,转换成十六进制为:0x55

bytes[1]

(byte) ((value >> 8) & 0xFF):>>是右移操作,(value >> 8) 是先将value的所有位向右移动8位,移动后的左边(高位)会填充0(因为是无符号右移)。
( 5623658 ) 10 (5623658)_{10} (5623658)10 ( 0101 0101 1100 1111 0110 1010 ) 2 (0101\ 0101\ 1100\ 1111\ 0110\ 1010)_2 (0101 0101 1100 1111 0110 1010)2,(5623658>> 8)得到的是 ( 0000 0000 0101 0101 1100 1111 ) 2 (0000\ 0000\ 0101\ 0101\ 1100\ 1111)_2 (0000 0000 0101 0101 1100 1111)2

& 0xFF:是按位与运算,得到最后8位, ( 0000 0000 0101 0101 1100 1111 ) 2 (0000\ 0000\ 0101\ 0101\ 1100\ 1111)_2 (0000 0000 0101 0101 1100 1111)2 & 0xFF 得到的是 ( 1100 1111 ) 2 (1100\ 1111)_2 (1100 1111)2

所以bytes[0]的二进制值为:1100 1111,转换成十六进制为:0xCF

bytes[2]

(byte) (value & 0xFF) :是按位与运算,得到最后8位, ( 0101 0101 1100 1111 0110 1010 ) 2 (0101\ 0101\ 1100\ 1111\ 0110\ 1010)_2 (0101 0101 1100 1111 0110 1010)2 & 0xFF得到的是 ( 0110 1010 ) 2 (0110\ 1010)_2 (0110 1010)2

所以bytes[2]的二进制值为:0110 1010,转换成十六进制为:0x6A

bytes发送到硬件设备,硬件设备接收到的就是0x55CF6A

4、当value大于16777215时,转换为4个字节,4个字节能表示无符号的范围为0 ~ 2 32 2^{32} 232-1,即0~4294967295

int在java中是有符号数,int的取值范围为- 2 31 2^{31} 231 ~ 2 31 2^{31} 231-1,即-2147483648~2147483648

例如:
int value = 316777215,转换成二进制为:0001 0010 1110 0001 1010 0010 1111 1111

( 316777215 ) 10 (316777215)_{10} (316777215)10 ( 0001 0010 1110 0001 1010 0010 1111 1111 ) 2 (0001\ 0010\ 1110\ 0001\ 1010\ 0010\ 1111\ 1111)_2 (0001 0010 1110 0001 1010 0010 1111 1111)2

转换成二进制超过24位,占用32位,占用4个字节

int value =316777215
byte[] bytes= new byte[4];
bytes[0] =(byte) ((value >> 24) & 0xFF);
bytes[1] =(byte) ((value >> 16) & 0xFF);
bytes[2] =(byte) ((value >> 8) & 0xFF);
bytes[3] =(byte) (value & 0xFF);

bytes[0]

(byte) ((value >> 24) & 0xFF):>>是右移操作,(value >> 24) 是先将value的所有位向右移动24位,移动后的左边(高位)会填充0(因为是无符号右移)。
( 316777215 ) 10 (316777215)_{10} (316777215)10 ( 0001 0010 1110 0001 1010 0010 1111 1111 ) 2 (0001\ 0010\ 1110\ 0001\ 1010\ 0010\ 1111\ 1111)_2 (0001 0010 1110 0001 1010 0010 1111 1111)2,(316777215>> 24)得到的是 ( 00000 0000 0000 0000 0000 0000 0001 0010 ) 2 (00000\ 0000\ 0000\ 0000\ 0000\ 0000\ 0001\ 0010)_2 (00000 0000 0000 0000 0000 0000 0001 0010)2

& 0xFF:是按位与运算,得到最后8位, ( 00000 0000 0000 0000 0000 0000 0001 0010 ) 2 (00000\ 0000\ 0000\ 0000\ 0000\ 0000\ 0001\ 0010)_2 (00000 0000 0000 0000 0000 0000 0001 0010)2 & 0xFF 得到的是 ( 0001 0010 ) 2 (0001\ 0010)_2 (0001 0010)2

所以bytes[0]的二进制值为:0001 0010,转换成十六进制为:0x12

bytes[1]

(byte) ((value >> 16) & 0xFF):>>是右移操作,(value >> 16) 是先将value的所有位向右移动16位,移动后的左边(高位)会填充0(因为是无符号右移)。
( 316777215 ) 10 (316777215)_{10} (316777215)10 ( 0001 0010 1110 0001 1010 0010 1111 1111 ) 2 (0001\ 0010\ 1110\ 0001\ 1010\ 0010\ 1111\ 1111)_2 (0001 0010 1110 0001 1010 0010 1111 1111)2,(316777215>> 16)得到的是 ( 00000 0000 0000 0000 0001 0010 1110 0001 ) 2 (00000\ 0000\ 0000\ 0000\ 0001\ 0010\ 1110\ 0001)_2 (00000 0000 0000 0000 0001 0010 1110 0001)2

& 0xFF:是按位与运算,得到最后8位, ( 00000 0000 0000 0000 0001 0010 1110 0001 ) 2 (00000\ 0000\ 0000\ 0000\ 0001\ 0010\ 1110\ 0001)_2 (00000 0000 0000 0000 0001 0010 1110 0001)2 & 0xFF 得到的是 ( 1110 0001 ) 2 (1110\ 0001)_2 (1110 0001)2

所以bytes[0]的二进制值为:1110 0001,转换成十六进制为:0xE1

bytes[2]

(byte) ((value >> 8) & 0xFF):>>是右移操作,(value >> 8) 是先将value的所有位向右移动8位,移动后的左边(高位)会填充0(因为是无符号右移)。
( 316777215 ) 10 (316777215)_{10} (316777215)10 ( 0001 0010 1110 0001 1010 0010 1111 1111 ) 2 (0001\ 0010\ 1110\ 0001\ 1010\ 0010\ 1111\ 1111)_2 (0001 0010 1110 0001 1010 0010 1111 1111)2,(316777215>> 8)得到的是 ( 00000 0000 0001 0010 1110 0001 1010 0010 ) 2 (00000\ 0000\ 0001\ 0010\ 1110\ 0001\ 1010\ 0010)_2 (00000 0000 0001 0010 1110 0001 1010 0010)2

& 0xFF:是按位与运算,得到最后8位, ( 00000 0000 0001 0010 1110 0001 1010 0010 ) 2 (00000\ 0000\ 0001\ 0010\ 1110\ 0001\ 1010\ 0010)_2 (00000 0000 0001 0010 1110 0001 1010 0010)2 & 0xFF 得到的是 ( 1010 0010 ) 2 (1010\ 0010)_2 (1010 0010)2

所以bytes[0]的二进制值为:1010 0010,转换成十六进制为:0xA2

bytes[3]

(byte) (value & 0xFF) :是按位与运算,得到最后8位, ( 0001 0010 1110 0001 1010 0010 1111 1111 ) 2 (0001\ 0010\ 1110\ 0001\ 1010\ 0010\ 1111\ 1111)_2 (0001 0010 1110 0001 1010 0010 1111 1111)2 & 0xFF得到的是 ( 1111 1111 ) 2 (1111\ 1111)_2 (1111 1111)2

所以bytes[2]的二进制值为:1111 1111,转换成十六进制为:0xFF

bytes发送到硬件设备,硬件设备接收到的就是0x12E1A2FF

总结:int转byte数组

将int数值转换为占四个字节的byte数组,如下

    /*** 将int数值转换为占四个字节的byte数组,(高位在前,低位在后的顺序)。** @param value 要转换的int值* @return byte数组*/public static byte[] intToBytes(int value) {byte[] src = new byte[4];src[0] = (byte) ((value >> 24) & 0xFF);src[1] = (byte) ((value >> 16) & 0xFF);src[2] = (byte) ((value >> 8) & 0xFF);src[3] = (byte) (value & 0xFF);return src;}

二、byte数组转int

1、当byte数组的长度为1时,占用1个字节

例如:

byte[] bytes= new byte[]{(byte) 0xF6};

0xF6 转换成二进制为 1111 0110

byte[] bytes= new byte[]{(byte) 0xF6};
int value = 	bytes[0]  & 0xFF;

(byte) (bytes[0] & 0xFF):这是一个与操作,0xFF是十六进制,转换成二进制为:1111 1111,转换成十进制为:255,当bytes[0]和0xFF按位与运算时,得到的是bytes[0]的最后8位(低8位),其余高位将被清零。

value的二进制就为:1111 0110,转换成十进制为:246

所以byte[] bytes= new byte[]{(byte) 0xF6};bytes转换位int就为:246

2、当byte数组的长度为2时,占用2个字节

例如:

byte[] bytes= new byte[]{(byte) 0x0E,(byte) 0x4A};

0x0E 转换成二进制为 0000 1110

0x4A 转换成二进制为 0100 1010

byte[] bytes= new byte[]{(byte) 0x0E,(byte) 0x4A};
int value = ((bytes[0] & 0xFF) << 8)  |  (bytes[1] & 0xFF)

bytes[0] & 0xFF :操作确保这个字节被当作无符号数处理
<< 8:这是一个左移位操作。如果 (bytes[0] & 0xFF) 得到了一个无符号的8位数值,那么 << 8 将这个数值向左移动8位。

((bytes[0] & 0xFF) << 8) 得到 0000 1110 0000 0000

(bytes[1] & 0xFF:操作确保这个字节被当作无符号数处理

(bytes[1] & 0xFF得到: 0100 1010

| 是按位或操作,它将左移后的第一个字节和第二个字节(同样经过位与操作以确保无符号处理)的值合并在一起,形成一个新的数值。

所以value的二进制为:0000 1110 0100 1010 ,转换成int为:3658

3、当byte数组的长度为3时,占用3个字节

例如:

byte[] bytes= new byte[]{(byte) 0x55,(byte) 0xCF,(byte) 0x6A};

0x55 转换成二进制为 0101 0101

0xCF 转换成二进制为 1100 1111

0x6A 转换成二进制为 0110 1010

byte[] bytes= new byte[]{(byte) 0x55,(byte) 0xCF,(byte) 0x6A};
int value = ((bytes[0] & 0xFF) << 16)  | ((bytes[1] & 0xFF) << 8)  |  (bytes[2] & 0xFF)

bytes[0] & 0xFF :操作确保这个字节被当作无符号数处理
<< 16:这是一个左移位操作。如果 (bytes[0] & 0xFF) 得到了一个无符号的8位数值,那么 << 16 将这个数值向左移动16位,低位补0。

((bytes[0] & 0xFF) << 16) 得到 0101 0101 0000 0000 0000 0000

bytes[1] & 0xFF :操作确保这个字节被当作无符号数处理
<< 8:这是一个左移位操作。如果 (bytes[0] & 0xFF) 得到了一个无符号的8位数值,那么 << 8 将这个数值向左移动8位,低位补0。

((bytes[1] & 0xFF) << 8) 得到 1100 1111 0000 0000

(bytes[2] & 0xFF:操作确保这个字节被当作无符号数处理

(bytes[2] & 0xFF得到: 0110 1010

所以value的二进制为:0101 0101 1100 1111 0110 1010 ,转换成int为:5623658

4、当byte数组的长度为4时,占用4个字节

例如:0x12E1A2FF

byte[] bytes= new byte[]{(byte) 0x12,(byte) 0xE1,(byte) 0xA2,(byte) 0xFF};

0x12 转换成二进制为 0001 0010

0xE1 转换成二进制为 1110 0001

0xA2 转换成二进制为 1010 0010

0xFF 转换成二进制为 1111 1111

byte[] bytes= new byte[]{(byte) 0x12,(byte) 0xE1,(byte) 0xA2,(byte) 0xFF};
int value = ((bytes[0] & 0xFF) << 24)  | ((bytes[0] & 0xFF) << 16)  
| ((bytes[1] & 0xFF) << 8)  |  (bytes[2] & 0xFF)

bytes[0] & 0xFF :操作确保这个字节被当作无符号数处理
<< 24:这是一个左移位操作。如果 (bytes[0] & 0xFF) 得到了一个无符号的8位数值,那么 << 24 将这个数值向左移动24位,低位补0。

((bytes[0] & 0xFF) << 24) 得到0001 0010 0000 0000 0000 0000 0000 0000

bytes[1] & 0xFF :操作确保这个字节被当作无符号数处理
<< 16:这是一个左移位操作。如果 (bytes[0] & 0xFF) 得到了一个无符号的8位数值,那么 << 16 将这个数值向左移动16位,低位补0。

((bytes[1] & 0xFF) << 16) 得到 1110 0001 0000 0000 0000 0000

bytes[2] & 0xFF :操作确保这个字节被当作无符号数处理
<< 8:这是一个左移位操作。如果 (bytes[0] & 0xFF) 得到了一个无符号的8位数值,那么 << 8 将这个数值向左移动8位,低位补0。

((bytes[2] & 0xFF) << 8) 得到 1010 0010 0000 0000

(bytes[3] & 0xFF:操作确保这个字节被当作无符号数处理

(bytes[3] & 0xFF得到: 1111 1111

| 是按位或操作,将4个字节拼接成一个新的数值

所以value的二进制为:0001 0010 1110 0001 1010 0010 1111 1111,转换成int为:316777215

总结:byte数组转int

将占四个字节的byte数组转换为int数值

    /*** 将占四个字节的byte数组转换为int数值,(高位在前,低位在后的顺序)。** @param src 占四个字节的byte数组* @return int数值*/public static int bytesToInt(byte[] src) {int value;value = (((src[0] & 0xFF) << 24)| ((src[1] & 0xFF) << 16)| ((src[2] & 0xFF) << 8)| (src[3] & 0xFF));return value;}
    /*** 将字节数组的一部分转换为整数。** @param bytes  字节数组* @param start  起始位置(包含)* @param length 要转换的字节长度* @return 转换后的整数*/public static int byteArrayToInt(byte[] bytes, int start, int length) {int result = 0;for (int i = start; i < start + length; i++) {result = result | ((bytes[i] & 0xFF) << ((start + length - i - 1) * 8));}return result;}

http://www.ppmy.cn/ops/19479.html

相关文章

物联网实战--驱动篇之(九)NB-IOT(BC260)

目录 一、NB-IOT简介 二、NB-IOT要素 三、代码详解 四、平台端 一、NB-IOT简介 实际上&#xff0c;就是NB-Iot彻底引爆了物联网的&#xff0c;大概2018年左右&#xff0c;NB推广如火如荼&#xff0c;同时广域网、低功耗的LPWAN网络也逐渐传开&#xff0c;现在回头来看&…

springboot项目打war包,并且部署外部tomcat中

参考&#xff1a;SpringBoot项目打包成war包并部署在tomcat上运行的操作步骤_java_脚本之家

Linux下软硬链接和动静态库制作详解

目录 前言 软硬链接 概念 软链接的创建 硬链接的创建 软硬链接的本质区别 理解软链接 理解硬链接 小结 动静态库 概念 动静态库的制作 静态库的制作 动态库的制作 前言 本文涉及到inode和地址空间等相关概念&#xff0c;不知道的小伙伴可以先阅读以下两篇文章…

如何使用IDEA直接连接MySQL数据库

如何使用IDEA直接连接MySQL数据库 新建一个空项目打开DataBase窗口连接数据库第一次连接 需要先下载驱动上一步驱动下载太慢怎么办&#xff1f;下载好驱动后 测试连接 新建一个空项目 打开DataBase窗口 连接数据库 第一次连接 需要先下载驱动 如果这里下载的很慢 看下一步解决…

Linux--自主编写shell

目录 准备知识 shell原理 shell与用户互动的过程 实现shell 0.用到的头文件和宏定义 1.首先我们需要自己输出一个命令行 2.获取用户命令行字符 3.命令行字符串分割 4.执行命令 5.设置循环 6.检测内建命令 7.完善细节--获取工作目录而非路径 准备知识 Linux--环境…

Pytorch 计算深度模型的大小

计算模型大小的方法 卷积 时间复杂度 与 空间复杂度 的计算方式&#xff1a; C 通道的个数&#xff0c;K卷积核大小&#xff0c;M特征图大小&#xff0c;C_l-1是输入通道的个数&#xff0c;C_l是输出通道的个数 1 模型大小 MB 计算模型的大小的原理就是计算保存模型所需要…

Android kotlin创建App实例

Android kotlin创建App实例 正常情况下&#xff0c;代码如下 class MyApp : Application() {override fun onCreate() {super.onCreate()instance this}companion object {private var instance: Application? nullfun instance() instance!!} }在这个情景下&#xff0c;…

python基础知识—while和for循环(三)

&#x1f3ac; 秋野酱&#xff1a;《个人主页》 &#x1f525; 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 一&#xff1a;while循环1.1程序的三种执行流程1.2while循环1.3循环变量和死循环 二&#xff1a;for循环2.1for循环2.2range 一&…