Java 无符号数据类型处理

前言

距离上一次博客已经过去很久了,原因有三

  • 其一:上一篇即将完成的博客未手动保存,系统亦未自动保存 导致热情降低
  • 其二:国庆小假期放飞自我
  • 其三:当前项目遇阻,进展缓慢

当前问题

说一说最近遇到的问题,之前实现了 Android 低功耗蓝牙的使用,为接入现有项目,需将数据先封装为 ModBus_RTU 协议帧,再通过蓝牙协议将 ModBus_RTU协议帧 透传至从机

项目整体架构如下:

熟悉嵌入式开发的朋友应该对 INT8UINT16U 等类型非常熟悉,它们分别代表的是 8位无符号整型,16位无符号整型。

既然是 8位/16位,首先想到的办法就是在 Java 中找到同字节的数据类型去替代使用

我选择的是 byte short 

随后注意到 Java 的基础数据类型中居然没有无符号类型(char 除外),而透传模块传输过来的数据是无符号的

类型默认值占用存储空间 范围范围说明
byte01byte(8bit)-128~127-2 的 7 次方到 2 的7次方 - 1
short02byte(16bit)-32768~32767-2 的 15 次方到 2 的 15 次方 - 1
int04byte(32bit)-2147483648~2147483647-2 的 31 次方到 2 的 31 次方 - 1
long08byte(64bit)-9223372036854774808~9223372036854774807-2 的 63 次方到 2 的 63 次方 - 1
float0.04byte(32bit)3.402823e+38 ~ 1.401298e-45e+38 表示是乘以 10 的 38 次方,同样,e-45 表示乘以 10 的负 45 次方
double0.08byte(64bit)1.797693e+308~ 4.9000000e-324 
char2byte(16bit)\u0000~\uFFFFchar 类型变量是用来存储 Unicode 编码的字符,可以存储一个汉字,汉字在 Unicode编码中占用两个字节
booleanFALSE1byte(8bit)false、true 

关于 char 的编码,可以看看阮一峰老师的 字符编码笔记

那么蓝牙通讯时,协议封装和解析时就要特别注意到有符号数据和无符号数据之间的转换

否则可能出现以下情况:

 Android 端接收到 INT8U 数据255(0xFF),若直接将一个 byte 变量赋值为0xFF,则将被 Java 解析为 -1。这种结果当然是我们不愿意看到的。

解决方法

接收数据时(无符号数据 ---> 有符号数据)

当前解决方法是在 Java 中用更高的存储数据类型

例如 需要接收 INT8U 数据,则需在 Java 中使用 16+bit 数据存储例如 shortint...

//Android 蓝牙接收到 byte[],byte[0] = 0xFF = 255(无符号数据)
byte a = (byte)0xFF;

System.out.println(UINT8toRead(a));


//...

public int UINT8toRead(byte a)
{
    //部分编译器会把最高位当做符号位,因此写成 0x0FF
    int read = a & 0x0FF;
    //read = a;
    //read = (read<<8)>>>8;
    return read;
}

0xFF Java 会被解析为 int 数据,因而 

& 操作在这里返回的结果是一个 int 类型(int & byte)

<<  是左移

>>>  是无符号右移

结果:

此外我们还可以使用 Guava ,参见

Google Guava 快速入门 —— 原生类型工具类

Google Guava 的 5 个鲜为人知的特性

发送数据时(有符号数据 ---> 无符号数据)

同样以 8位数据 为例,例如需要发送 255,那么协议中使用 byte 进行存储,如何操作?

//待发送数据为255
int write = 255;

System.out.println(WritetoUINT8(write));


//...

public byte WritetoUINT8(int write)
{
    //在协议中该数据保存为byte a
    byte a = (byte)(write & 0x0FF);
    return a;
}

结果:

查看其二进制编码: 

8bit 无符号类型中, 0xFF 将被解析为 255

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值