我通过BLE收到了一个4字节长的数组,我有兴趣将最后两个字节转换为浮点十进制表示形式(float
, double
等)。原始值具有以下格式:
1 sign bit
4 integer bits
11 fractional bits
我的第一次尝试是使用BitConverter
,但是我对该程序感到困惑。
示例:我收到一个byte
数组values
,其中values[2] = 143
和values[3] = 231
。合并的这2个字节表示上面指定格式的值。我不确定,但我认为会是这样:
SIGN INT FRACTION
0 0000 00000000000
此外,由于该值以两个字节为单位,因此我尝试使用BitConverter.ToString
来获取十六进制表示形式,然后将这些字节连接起来。在这一点上,我不确定如何继续。
谢谢您的帮助!
答案 0 :(得分:4)
您的问题缺少信息,但是格式似乎很明确,例如给定的两个字节为
byte[] arr = new byte[] { 123, 45 };
我们有
01111011 00101101
^^ ^^ .. ^
|| || |
|| |11 fractional bits = 01100101101 (813)
||..|
|4 integer bits = 1111 (15)
|
1 sign bit = 0 (positive)
让我们了解所有部分:
bool isNegative = (arr[0] & 0b10000000) != 0;
int intPart = (arr[0] & 0b01111000) >> 3;
int fracPart = ((arr[0] & 0b00000111) << 8) | arr[1];
现在,我们应该将所有这些部分组合成一个数字;这是歧义:计算分数部分的方法有很多。
是其中之一 result = [sign] * (intPart + fracPart / 2**Number_Of_Frac_Bits)
在我们的情况下,{ 123, 45 }
,我们有
sign = 0 (positive)
intPart = 1111b = 15
fracPart = 01100101101b / (2**11) = 813 / 2048 = 0.39697265625
result = 15.39697265625
实施:
// double result = (isNegative ? -1 : 1) * (intPart + fracPart / 2048.0);
Single result = (isNegative ? -1 : 1) * (intPart + fracPart / 2048f);
Console.Write(result);
结果:
15.39697
编辑:如果您实际上没有符号位,但对整数部分使用 2的补码(即不寻常-double
,float
使用sign bit; 2的补码适用于整数类型,例如Int32
,Int16
等),我期望只是一个期望,在上下文中2的补码是不寻常的),例如
int intPart = (arr[0]) >> 3;
int fracPart = ((arr[0] & 0b00000111) << 8) | arr[1];
if (intPart >= 16)
intPart = -((intPart ^ 0b11111) + 1);
Single result = (intPart + fracPart / 2048f);
您实际上使用整数值(Int16
)和固定浮点数的另一种可能性;在这种情况下,转换很容易:
Int16
2048.0
除以固定浮点数:代码:
// -14.01221 for { 143, 231 }
Single result = unchecked((Int16) ((arr[0] << 8) | arr[1])) / 2048f;
或
Single result = BitConverter.ToInt16(BitConverter.IsLittleEndian
? arr.Reverse().ToArray()
: arr, 0) / 2048f;