Java 如何将大整数转换为字节

Java 如何将大整数转换为字节,java,c,type-conversion,bytearray,processing,Java,C,Type Conversion,Bytearray,Processing,我需要通过串行通信将值115200作为参数发送到外部设备,该设备需要参数作为字节数组的一部分,格式为:0x00,0x00,0x00,0x00,我不知道如何将其转换为该格式。 我是在Processing中这样做的,所以Processing/java解决方案在将来会很方便,但是如果我能用这个特定变量发送消息,我非常高兴 以下是字节数组: byte[] tx_cmd = { 0x55, -86, // packet header (-86 == 0xAA)

我需要通过串行通信将值
115200
作为参数发送到外部设备,该设备需要参数作为字节数组的一部分,格式为:
0x00,0x00,0x00,0x00
,我不知道如何将其转换为该格式。 我是在Processing中这样做的,所以Processing/java解决方案在将来会很方便,但是如果我能用这个特定变量发送消息,我非常高兴

以下是字节数组:

byte[] tx_cmd = { 0x55, -86,             // packet header (-86 == 0xAA) 
                0x01, 0x00,              // device ID
                0x00, 0x00, 0x00, 0x00,  // input parameter NEEDS TO BE 115200
                0x04, 0x00,              // command code
                0x00, 0x01 };            // checksum
参数需要放在第5到第8位(字节[4]-字节[7])

消息格式为little endian这是消息结构:

0 0x55字节的命令开始代码1

1 0xAA字节命令开始代码2

2设备ID字设备ID:默认值为0x0001,始终固定

4参数DWORD输入参数

8命令字命令代码

10校验和字 校验和(字节加法) 偏移量[0]+…+偏移量[9]=校验和

任何建议都将不胜感激。
谢谢

您需要屏蔽和转换

int num = 115200
int b1 = (num & 0xff000000) >> 24
int b2 = (num & 0x00ff0000) >> 16
int b3 = (num & 0x0000ff00) >> 8
int b4 = (num & 0x000000ff) >> 0
您尝试将int打包为字节,但没有提及它是否为网络顺序,因此我们假设它是(例如,第一个字节tx_cmd[4]是数字的最高字节):


一般来说,使用
int_to_bytes
等函数非常方便,它们以通用的方式完成这项工作,并使代码不那么凌乱。

对于预期采用小端格式的字节,您可以按如下方式设置它们:

uint32_t value = 115200;
tx_cmd[4] = value & 0xff;
tx_cmd[5] = (value >> 8) & 0xff;
tx_cmd[6] = (value >> 16) & 0xff;
tx_cmd[7] = (value >> 24) & 0xff;

重要的是,您正在使用的值是无符号的,否则,如果设置了最高有效位,则有可能将1移入。

建议创建一个函数来打包所有内容

#define byte_n(x, b) ((x >> (b*8)) & 0xFF)

void CreatePacket(byte tx_cmd[], uint16_t device_id, uint32_t param, uint16_t command) {
  #define HEADER 0xAA55
  tx_cmd[0] = byte_n(HEADER, 0);
  tx_cmd[1] = byte_n(HEADER, 1);
  tx_cmd[2] = byte_n(device_id, 0);
  tx_cmd[3] = byte_n(device_id, 1);
  tx_cmd[4] = byte_n(param, 0);
  tx_cmd[5] = byte_n(param, 1);
  tx_cmd[6] = byte_n(param, 2);
  tx_cmd[7] = byte_n(param, 3);
  tx_cmd[8] = byte_n(command, 0);
  tx_cmd[9] = byte_n(command, 1);
  unsigned checksum = 0;
  for (int i=0; i<10; i++) {
    checksum += tx_cmd[i];
  }
  tx_cmd[10] = byte_n(checksum, 0);
  tx_cmd[11] = byte_n(checksum, 1);
}

byte tx_cmd[12];
device_id = 1;
baud = 115200;
command = 4;
CreatePacket(tx_cmd, device_id,  baud, command);
#定义字节n(x,b)((x>>(b*8))&0xFF)
void CreatePacket(字节tx_cmd[],uint16_t设备id,uint32_t参数,uint16_t命令){
#定义标头0xAA55
tx_cmd[0]=字节(头,0);
tx_cmd[1]=字节n(头,1);
tx_cmd[2]=字节n(设备id,0);
tx_cmd[3]=字节(设备id,1);
tx_cmd[4]=字节n(参数,0);
tx_cmd[5]=字节n(参数,1);
tx_cmd[6]=字节n(参数,2);
tx_cmd[7]=字节n(参数,3);
tx_cmd[8]=字节n(命令,0);
tx_cmd[9]=字节n(命令,1);
无符号校验和=0;

对于(int i=0;iis),您的问题是如何将
int
转换为sizeof(int)大小的字节数组?或者它的值是否准确?可能与预期的endian完全相同-115200的最低或最高有效字节是否进入字节[4]?(消息显示为little endian)。你知道如何计算校验和吗?如果不知道,使用什么算法以及它是如何应用的?也许这个协议/格式有一个名字???@HannesAndersson:你说过你正在控制的设备是小端。现在的问题是-进行控制的设备的端度是多少?如果它显然是大端,你必须这样做交换字节(如提供的解决方案所示)如果执行控制的设备是小端结构,并且被控制的设备需要小端结构值,那么您不必进行字节交换。请在交叉柱之间链接:这是一个有符号整数,移动它们可能会产生奇怪的结果。最好使用无符号。感谢您的回答,但它会引发错误:
运算符&&未定义参数类型int,int
知道我做错了什么吗?哦,我的错-应该是&谢谢你的回答!尽管我没有让它工作,因为这会导致:
[4]0[5]1[6]194[7]0
,所以[6]仍然是个大数字,知道我做错了什么吗?194不是太大-你为什么说它是?@HannesAndersson 0,1,194,0(十进制)是0x00,0x01,0xC2,0x00(十六进制),这是0x0001C200=115200的十进制。显然它现在是大端形式。对我来说似乎是对的。非常感谢!这确实很方便!
#define byte_n(x, b) ((x >> (b*8)) & 0xFF)

void CreatePacket(byte tx_cmd[], uint16_t device_id, uint32_t param, uint16_t command) {
  #define HEADER 0xAA55
  tx_cmd[0] = byte_n(HEADER, 0);
  tx_cmd[1] = byte_n(HEADER, 1);
  tx_cmd[2] = byte_n(device_id, 0);
  tx_cmd[3] = byte_n(device_id, 1);
  tx_cmd[4] = byte_n(param, 0);
  tx_cmd[5] = byte_n(param, 1);
  tx_cmd[6] = byte_n(param, 2);
  tx_cmd[7] = byte_n(param, 3);
  tx_cmd[8] = byte_n(command, 0);
  tx_cmd[9] = byte_n(command, 1);
  unsigned checksum = 0;
  for (int i=0; i<10; i++) {
    checksum += tx_cmd[i];
  }
  tx_cmd[10] = byte_n(checksum, 0);
  tx_cmd[11] = byte_n(checksum, 1);
}

byte tx_cmd[12];
device_id = 1;
baud = 115200;
command = 4;
CreatePacket(tx_cmd, device_id,  baud, command);