我正在尝试编写代码,让我将 CAN 消息的数据字段的值打印为一系列十六进制形式的短裤。CAN 消息数据字段包含 4 个 short,例如,我可能会打印出一条消息为“FFFF EEEE ABAB 2013”。
我可以将 CAN 消息的 2 个短片编码为一个整数值,只要未设置整数的第 32 位,一切都可以正常工作。因为 Java 使用有符号整数,所以设置第 32 位会导致它打印出一系列“f”。我想要的是整数充当无符号值,以便将其打印出来不会引起问题。
这是一个出错的例子:
(int value): 0x80000000
(string rep short 1): 0xffff8000
<crash>
以下是它在其他情况下的工作方式:
(int value): 0x40000000
(string rep short 1): 0x4000
(string rep short 2): 0x0
我尝试表示 CAN 消息数据以及发生崩溃的代码:
public String getFormattedData() {
String dataString = "";
for(String aShort : Utility.splitStringByWhitespace(getData())) {
try{
dataString += ("0000".substring(0, 4 - aShort.length()) + aShort) + " ";
} catch(Exception e) {
System.out.println(getData());
System.exit(1);
}
}
return dataString.toUpperCase();
}
具体来说,崩溃的发生是因为“f”s 将 short 的字符串表示的长度增加到 8 个字符,因此“4 - aShort.length()”将产生一个负值,这是无效的。
编辑:对于那些询问的人,在这种特殊情况下,这就是我在将数据转换为字符串表示之前使用整数对数据进行编码的方式:
public String convertToCANMessageData(PWMChannel channel) {
int channelVal = channel.getValue();
int entryDataHI = 0, entryDataLO = 0;
entryDataHI += channelVal << 24;
entryDataHI += smallData << 8;
entryDataHI += (largeData >> 8) & 0xFF;
entryDataLO += (largeData & 0xFF) << 24;
if(ramping) {
entryDataHI = entryDataHI | (1 << 16);
} else {
entryDataHI = entryDataHI & ~(1 << 16);
}
if(jumping) {
entryDataHI = entryDataHI | (1 << 17);
} else {
entryDataHI = entryDataHI & ~(1 << 17);
}
if(frequencySetting) {
entryDataHI = entryDataHI | (1 << 18);
} else {
entryDataHI = entryDataHI & ~(1 << 18);
}
return String.format("%x %x %x %x", entryDataHI >> 16, entryDataHI & 0xFFFF,
entryDataLO >> 16, entryDataLO & 0xFFFF);
}