Dart 将 IEEE-11073 32 位 FLOAT 转换为简单的双精度数

Dart Convert IEEE-11073 32-bit FLOAT to a simple double

我在处理这些低级字节和数字方面没有太多经验,所以我来这里寻求帮助。我在我的 Flutter 应用程序中连接了一个蓝牙温度计,并且根据他们的文档,我得到了一组格式如下的数字。 I'm attempting to convert these numbers to a plain temperature double, but can't figure out how. This is the "example" the company gives me. 但是,当我的温度计读数为 98.5 时,我得到的响应是 [113, 14, 0, 254]

的数组

感谢您的帮助!

IEEE-11073 是医疗设备中常用的格式。你引用的 table 里面有你解码数字的所有内容,尽管一开始可能很难破译。

让我们以您的第一个示例为例:0xFF00016C。这是一个 32 位数字,第一个字节是指数,最后三个字节是尾数。两者都以 2s 补码表示形式编码:

  • 指数,0xFF,在 2 的补码中,这是数字 -1
  • 尾数,0x00016C,在 2 的补码中,这是数字 364

(如果您不太确定数字如何以 2 的补码编码,请将其作为一个单独的问题提出。)

我们接下来要做的是确保它不是 "special" 值,正如您 table 中所规定的那样。由于您的指数不是 0(而是 -1),我们知道您没问题。所以,不需要特殊处理。

由于这个值并不特殊,所以它的数值就是:mantissa * 10^exponent。因此,我们有:364*10^-1 = 36.4,如您的示例所示。

你的第二个例子是相似的。指数是 0xFE,也就是 2 的补码中的数字 -2。尾数为0x000D97,十进制为3479。同样,指数不为 0,因此不需要特殊处理。所以你有:3479*10^-2 = 34.79.

你说 98.5 值,你得到字节数组 [113, 14, 0, 254]。让我们看看我们是否能理解这一点。你的字节数组,用十六进制写成:[0x71, 0x0E, 0x00, 0xFE]。我猜你以 "reverse" 顺序接收这些字节,所以作为 32 位十六进制,这实际上是 0xFE000E71.

我们以类似的方式进行:指数再次为 -2,因为 0xFE 是您使用 8 位以 2 的补码形式编写 -2 的方式。 (见上文。)尾数是 0xE71,等于 3697。所以,这个数字是 3697*10^-2 = 36.97.

您声称这实际上是 98.5。我最好的猜测是您正在以华氏度阅读它,而您的设备正在以摄氏度报告。如果您计算一下,您会发现 36.97C = 98.55F 已经足够接近了。我不确定您是如何获得 98.5 数字的,但是对于这样的设备,此结果似乎在您可以预期的精度范围内。

希望对您有所帮助!

这是我用来在我们的 flutter 应用程序中将 sfloat16 转换为 double in dart 的东西。

double sfloat2double(ieee11073) {
    var reservedValues = {
            0x07FE: 'PositiveInfinity',
            0x07FF: 'NaN',
            0x0800: 'NaN',
            0x0801: 'NaN',
            0x0802: 'NegativeInfinity'
        };
    var mantissa = ieee11073 & 0x0FFF;

    
    if (reservedValues.containsKey(mantissa)){
      return 0.0; // basically error
    }
  
    if ((ieee11073 & 0x0800) != 0){
       mantissa =  -((ieee11073 & 0x0FFF) + 1 );
    }else{
      mantissa = (ieee11073 & 0x0FFF);  
    }
    
    var exponent = ieee11073 >> 12;
    if (((ieee11073 >> 12) & 0x8) != 0){
      exponent = -((~(ieee11073 >> 12) & 0x0F) + 1 );
    }else{
      exponent = ((ieee11073 >> 12) & 0x0F); 
    }
    var magnitude = pow(10, exponent);
    return (mantissa * magnitude);  
}