将浮点字节数组转换为十进制

时间:2018-07-26 09:22:17

标签: c# floating-point bluetooth-lowenergy

我通过BLE收到了一个4字节长的数组,我有兴趣将最后两个字节转换为浮点十进制表示形式(floatdouble等)。原始值具有以下格式:

 1 sign bit 
 4 integer bits 
11 fractional bits

我的第一次尝试是使用BitConverter,但是我对该程序感到困惑。

示例:我收到一个byte数组values,其中values[2] = 143values[3] = 231。合并的这2个字节表示上面指定格式的值。我不确定,但我认为会是这样:

SIGN  INT FRACTION  
   0 0000 00000000000

此外,由于该值以两个字节为单位,因此我尝试使用BitConverter.ToString来获取十六进制表示形式,然后将这些字节连接起来。在这一点上,我不确定如何继续。

谢谢您的帮助!

1 个答案:

答案 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的补码(即不寻常-doublefloat使用sign bit; 2的补码适用于整数类型,例如Int32Int16等),我期望只是一个期望,在上下文中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)和固定浮点数的另一种可能性;在这种情况下,转换很容易:

  1. 我们照常获得Int16
  2. 然后用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;