另一方面,基于字节数组的方法可能是这样的:
int extend(uint raw, int bits)
{
int sh = 32 - bits;
int x = (int)raw << sh; // puts your sign bit in the highest bit.
return x >> sh; // since x is signed this is an arithmatic signed shift
}
int read(byte[] data, int pos, int bits, bool signed)
{
int fbi = pos / 8; // first byte index
int lbi = (pos + bits - 1) / 8; // last byte index
int cnt = lbi - fbi + 1; // bytes spanned
if (cnt > 3 || lbi >= data.Length) { throw new ArgumentException(); }
uint raw = (uint)(
(data[fbi] << (24 + pos % 8)) +
(cnt < 2 ? 0 : data[fbi + 1] << (16 + pos % 8)) +
(cnt < 3 ? 0 : data[fbi + 2] << (8 + pos % 8))
) >> (32 - bits);
return signed ? extend(raw, bits) : (int)raw;
}
对此进行测试:
byte[] test = { 0x55, 0xAA, 0x10 };
string s = "";
s += read(test, 0, 8, false) + "\r\n";
s += read(test, 0, 8, true) + "\r\n";
s += read(test, 8, 8, false) + "\r\n";
s += read(test, 8, 8, true) + "\r\n";
s += read(test, 4, 8, false) + "\r\n";
s += read(test, 7, 9, true) + "\r\n";
s += read(test, 7, 10, true) + "\r\n";
s += read(test, 7, 11, true) + "\r\n";
s += read(test, 7, 12, true) + "\r\n";
s += read(test, 7, 13, true) + "\r\n";
s += read(test, 7, 14, true) + "\r\n";
s += read(test, 7, 15, true) + "\r\n";
s += read(test, 7, 16, true) + "\r\n";
s += read(test, 7, 17, true) + "\r\n";
s += read(test, 18, 2, true) + "\r\n";
s += read(test, 18, 3, true) + "\r\n";
s += read(test, 23, 1, true) + "\r\n";
s += read(test, 23, 2, true) + "\r\n";
测试构建字符串,如下所示:
85
85
170
-86
90
-86
-172
-344
-688
-1375
-2750
-5500
-11000
-22000
1
2
0
然后在最后一行抛出异常。