Java byte数组转有符号int

来源:互联网 发布:unity3d在线培训 编辑:程序博客网 时间:2024/06/01 20:02

前言

最近在写Java蓝牙串口通信读取数据中,需要将读取到的十六进制数转换为16位的有符号整数,网上Google一大堆,均无果,最后在StackOverFlow上找到了答案。

问题描述

通信协议上指出需要需要解析出三个16位的int型数据,每个数据2个字节,即2个byte。
通信协议

温习一下java数据类型基础知识: byte型占1个字节,int型占4个字节,在java中没有无符号的数据类型。

下面是官方给的C#示例程序代码:
C#示例程序
虽然没学过C#,但还是可以看出处理过程:
首先从原始数据byteTemp取出有用的部分复制到raw字节数组中,也就是raw中存放需要处理的两个字节,再调用自带的数组转置函数倒转一下顺序(应该是通信协议的要求),最后关键的一步调用BitConverter.ToInt16将2个字节转成一个16位的有符号整型数据。可见C#的各种小工具类还是挺全的,唉,此处不忍心要吐槽java了…
那么问题来了,如何将2个字节的字节数组转换成有符号的整型数据呢?也就是C#自带的API: BitConverter.ToInt16(byte[] src, int startIndex)在java中应该如何手动实现呢?

查看MSDN

打开微软的官方API文档想一探究竟,结果被吓得怀疑人生了,怀疑自己到底有没有学过计算机…这究竟怎么转的啊…怎么0F00就是15,F1FF就变成-15呢,郁闷…
C#API

Google搜索

  • Java 中int与byte数组转换详解 http://my.oschina.net/u/169390/blog/97495
  • Java 中 byte、byte 数组和 int、long 之间的转换
    http://blog.csdn.net/defonds/article/details/8782785
  • java中byte, int的转换
    http://freewind886.blog.163.com/blog/static/661924642011810236100/

无奈,先查阅各种资料,补充了点基础知识,学到了一些基本转换。

byte转换为int

两种情况:
1. 保持值不变,如进行数值运算,采用强制转换: int aInt = (int) aByte;
2. 保持低位不变,高位用0填充,如编码解码操作,采用位操作: int aInt = aByte & 0xFF;

int转换为byte

直接使用强制类型转换: byte aByte = (byte) aInt; 但注意前提是int值小于255

有符号byte数组与int相互转换

public static int byteArrayToInt(byte[] b) {      return   b[3] & 0xFF |              (b[2] & 0xFF) << 8 |              (b[1] & 0xFF) << 16 |              (b[0] & 0xFF) << 24;  }  public static byte[] intToByteArray(int a) {      return new byte[] {          (byte) ((a >> 24) & 0xFF),          (byte) ((a >> 16) & 0xFF),             (byte) ((a >> 8) & 0xFF),             (byte) (a & 0xFF)      };  }  // 任意长度public static int toInt(byte[] bRefArr) {    int iOutcome = 0;    byte bLoop;    for (int i = 0; i < bRefArr.length; i++) {        bLoop = bRefArr[i];        iOutcome += (bLoop & 0xFF) << (8 * i);    }    return iOutcome;}

StackOverFlow找到答案

说实话,StackOverFlow才是真正的神器啊!

Convert from 2 or 4 bytes to signed/unsigned short/int
http://stackoverflow.com/questions/10803557/convert-from-2-or-4-bytes-to-signed-unsigned-short-int

StackOverFlow
其中第一个是有符号类型的,第二个是无符号类型。
此处贴上该问题正确的代码:

public class IntegerConversion{  public static int convertTwoBytesToInt1 (byte b1, byte b2)      // signed  {    return (b2 << 8) | (b1 & 0xFF);  }  public static int convertFourBytesToInt1 (byte b1, byte b2, byte b3, byte b4)  {    return (b4 << 24) | (b3 & 0xFF) << 16 | (b2 & 0xFF) << 8 | (b1 & 0xFF);  }  public static int convertTwoBytesToInt2 (byte b1, byte b2)      // unsigned  {    return (b2 & 0xFF) << 8 | (b1 & 0xFF);  }  public static long convertFourBytesToInt2 (byte b1, byte b2, byte b3, byte b4)  {    return (long) (b4 & 0xFF) << 24 | (b3 & 0xFF) << 16 | (b2 & 0xFF) << 8 | (b1 & 0xFF);  }  public static void main (String[] args)  {    byte b1 = (byte) 0xFF;    byte b2 = (byte) 0xFF;    byte b3 = (byte) 0xFF;    byte b4 = (byte) 0xFF;    System.out.printf ("%,14d%n", convertTwoBytesToInt1 (b1, b2));    System.out.printf ("%,14d%n", convertTwoBytesToInt2 (b1, b2));    System.out.printf ("%,14d%n", convertFourBytesToInt1 (b1, b2, b3, b4));    System.out.printf ("%,14d%n", convertFourBytesToInt2 (b1, b2, b3, b4));  }}

总结

  1. 不要小看基本数据类型以及各种位运算,这些往往才真的是难点,特别是对于java这种稀缺基本数据类型小工具包的语言
  2. 不要逃避问题,善用搜索引擎,还有给StackOverFlow点个赞
0 0