我有16位。在每个位中,我可以设置一些属性并发送到COM端口(财务打印机)。 例如:如果选中0位,则在检查时显示徽标。
这16位我需要转换为4个字节并发送到COM端口。 例如:如果检查0位,则4个字节将为0x30,0x31,0x30,0x30。 字节结果我得到了COM端口监控API。
我必须做什么,从16位获得4个字节?
其他例子:
答案 0 :(得分:2)
注意ASCII中的0x30 ='0'。它看起来像你将16位作为两个十六进制字节发送,第0-7位是第一位,8-15位,即你要传输
我们需要更多数据点才能确定,但这符合上述示例:
bit 0 set encodes to string "0100" = 0x30 0x31 0x30 0x30
bit 1 set "0200" = 0x30 0x32 0x30 0x30
bit 2 set "0400" = 0x30 0x34 0x30 0x30
0+2 "0500" = 0x30 0x30 0x30 0x30
0+9 "0102" = 0x30 0x31 0x30 0x32
0,1,2,3,4,5,9 "3F02" = 0x33 0x46 0x30 0x32
即。在Java中,如果你有一个整数n
中的位,你可能想要
String output = Integer.toHexString((n >> 4) & 0xf)
+ Integer.toHexString(n & 0xf)
+ Integer.toHexString((n >> 12) & 0xf)
+ Integer.toHexString((n >> 8) & 0xf);
byte[] data = output.toUpperCase().getBytes("ASCII");
通过字符串或
byte[] data = new byte[4];
data[0] = (byte)((n >> 4) & 0xf);
data[1] = (byte)(n & 0xf);
data[2] = (byte)((n >> 12) & 0xf);
data[3] = (byte)((n >> 8) & 0xf);
for(int i = 0; i < 4; ++i) {
data[i] += (data[i] < 10) ? '0' : ('A' - 10);
}
避免使用字符串。
要将四个字节解析回单个int,您可以使用
int bits = (((data[0] & 0xf) + ((data[0] >= 'A') ? 9 : 0)) << 4)
| ((data[1] & 0xf) + ((data[1] >= 'A') ? 9 : 0))
| (((data[2] & 0xf) + ((data[2] >= 'A') ? 9 : 0)) << 12)
| (((data[3] & 0xf) + ((data[3] >= 'A') ? 9 : 0)) << 8);
显然这里没有输入检查 - 我假设我们以预期的格式获得输入。括号中的主要部分应该只解析字符串中的单个十六进制数字 - 如果需要,您可以重构或实现更强大的数据。
答案 1 :(得分:0)
嗯,16位是2个字节。因此,如果将这两个字节分成两半,则会得到4个字节。
基本上是
byte b = ...;
byte firstHalf = (byte)((b & 0x0F) >> 4);
byte secondHalf = (byte)(b & 0xF0);
但请注意,这基本上只是分裂,不会提供您在问题中描述的结果。正如已经指出的那样,目前还不清楚应该检查“0”位是什么以及如何获得那些0x30 0x31 0x30 0x30值(你只能将16位分成4和4的数据包。将它们分别放入一个字节中。
答案 2 :(得分:0)
不确定你的意思:
你有16位,只有2个字节,所以你可以保留前2个字节0并在最后2个字节中使用16位......
Byte1: 0000 0000
Byte2: 0000 0000
Byte3: first 8 bits of your 16 bits
Byte4: second 8 bits of your 16 bits
编辑:我不明白你是怎么得到0x30,0x30,0x31,0x30
0x代表十六进制
0x30十六进制= 0011 0000 binairy 所以我不明白为什么你会使用0x30而不只是0x00 ...
答案 3 :(得分:0)
这个问题对解释有点开放,我认为你的意思是:
如果已设置,我必须检查16位数据类型的每个位。如果是的话 设置,然后我必须将数据发送到COM端口。我需要发送哪些数据 取决于设置的位。再见,我需要发送的数据总是4个字节。
假设需要检查的位是Java int
,即32位整数,其中高16位始终为0.我想建议使用BitSet来检查位和一个数组,用于定义设置该位时要发送的内容:
private static final byte [] [] BYTES_TO_SEND = new byte [] [] { {0x30,0x31,0x30,0x30},//检查位#0时要发送的数据 {0x42},//检查位#1时要发送的数据 // ...如果检查位#2,#3,...则要发送的数据 };
私人OutputStream com;
private static final byte[][] BYTES_TO_SEND = new byte[][] {
{ 0x30, 0x31, 0x30, 0x30 }, // data to send if bit #0 is checked
{ 0x42 }, // data to send if bit #1 is checked
// ... data to send if bit #2, #3, ... is checked
};
private OutputStream com;
public void initializeCOMFromBits(int bits) throws IOException {
for (byte[] toSendIfSet : BYTES_TO_SEND) {
if ((bits & 0x1) == 0x1) { // check if the lowest bit is set
com.write(toSendIfSet);
}
bits >>>= 1; // shift all bits by one to the left
// now the lowest bit if the bit that was second-to-lowest previously
}
assert bits == 0 : "There should be at most " + BYTES_TO_SEND.length + " bits set in the incoming bit set";
}
如果您的位在BitSet中,则将循环更改为带索引的for循环,并使用.get(i)
检查第i位 - 如果已设置,则将BYTES_TO_SEND[i]
发送到COM端口。