如何将二进制补码二进制byte []转换为十进制?

问题描述 投票:1回答:2

我通过字节选项卡(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

所以我需要帮助因为我不明白如何将包含二进制补码二进制的字节数据转换为十进制。

java byte twos-complement
2个回答
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
投票

将包含二进制补码值的任意字节数组转换为十进制表示的最简单方法是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。这不可能。如果您认为这是编码值,则必须调整您的规范。浮点值没有标准的三字节格式。

© www.soinside.com 2019 - 2024. All rights reserved.