我通过字节选项卡(byte[]
)从RS422通信接收数据。
我的一些数据采用以下规则的二进制补码:
Significant bits Two's complement
MSB LSB
00000000 0
00000001 + LSB
01111111 + MSB - LSB
10000000 - MSB
10000001 - MSB + LSB
11111111 - LSB
要将byte []数据转换为十进制,在纯二进制中,我使用以下代码:
Byte b05 = new Byte(new Integer(0x7A).byteValue()); // I use those bytes for my test
Byte b06 = new Byte(new Integer(0x00).byteValue());
Byte[] byteTabDay = new Byte[2] ;
byteTabDay[0] = b05 ;
byteTabDay[1] = b06 ;
int valueDay = byteTabDay[1] << 8 | byteTabDay[0] ;
System.out.println("day :" + valueDay); // print 122
但是我不知道如何像以前一样转换包含两个补码二进制数据的byte []:
Byte b20 = new Byte(new Integer(0x00).byteValue());
Byte b21 = new Byte(new Integer(0xFF).byteValue());
Byte b22 = new Byte(new Integer(0x3C).byteValue());
理论上,这些数据包含的值(或多或少):1176
所以我需要帮助因为我不明白如何将包含二进制补码二进制的字节数据转换为十进制。
答案 0 :(得分:2)
二进制补码二进制是表示包含负数的数字的标准。
对于三位数字:
Base 2 (One's Two's
complement) complement
000 = 0
001 = 1
010 = 2
011 = 3
100 = 4 -3 -4
101 = 5 -2 -3
110 = 6 -1 -2
111 = 7 -0 -1
Java假设有两个补码:最重要的一位是1表示否定... 同样在java字节中,short,int,long都是有符号的。 另外,您使用Object包装器作为基本类型。原始类型更直接。
byte b05 = (byte) 0x7A;
byte b06 = (byte) 0x00; // MSB, positive as < 0x80
nyte[] byteTabDay = new byte[2];
byteTabDay[0] = b05;
byteTabDay[1] = b06;
int valueDay = ((int) byteTabDay[1]) << 8) | (0xFF & byteTabDay[0]);
System.out.println("day :" + valueDay); // print 122
需要做什么:保持最高有效字节的符号扩展,但对于其他字节,通过用0xFF屏蔽它们将它们保持为8位。
答案 1 :(得分:1)
将包含二进制补码值的任意字节数组转换为十进制表示形式的最简单方法是new BigInteger(bytearray).toString()
。
但是,这要求数据采用大端字节顺序。如果数据按照您的问题中的小端顺序排列,则必须将其反转才能与BigInteger
一起使用。
byte[] bytearray={ 0x7A, 0x00 };
ByteBuffer b=ByteBuffer.allocate(bytearray.length);
for(int ix=bytearray.length; ix>0; ) b.put(bytearray[--ix]);
System.out.println(new BigInteger(b.array()).toString()); // print 122
如果数组的长度与标准原始值类型大小匹配,则可以使用ByteBuffer
直接获取值:
byte[] bytearray={ 0x7A, 0x00 };
System.out.println(ByteBuffer.wrap(bytearray)
.order(ByteOrder.LITTLE_ENDIAN).getShort()); // print 122
但是,不要期望值1176.61254
。这不可能。
如果您认为这是编码值,则必须调整您的规范。浮点值没有标准的三字节格式。