I don't have much experience working with these low level bytes and numbers, so I've come here for help. I'm connecting to a bluetooth thermometer in my Flutter app, and I get an array of numbers formatted like this according to their documentation. enter image description here 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. enter image description here However when I get a reading of 98.5 on the thermometer I get a response as an array of [113, 14, 0, 254]

Thanks for any help!


Solution 1: alias

IEEE-11073 is a commonly used format in medical devices. The table you quoted has everything in it for you to decode the numbers, though might be hard to decipher at first.

Let's take the first example you have: 0xFF00016C. This is a 32-bit number and the first byte is the exponent, and the last three bytes are the mantissa. Both are encoded in 2s complement representation:

  • Exponent, 0xFF, in 2's complement this is the number -1
  • Mantissa, 0x00016C, in 2's complement this is the number 364

(If you're not quite sure how numbers are encoded in 2's complement, please ask that as a separate question.)

The next thing we do is to make sure it's not a "special" value, as dictated in your table. Since the exponent you have is not 0 (it is -1), we know that you're OK. So, no special processing is needed.

Since the value is not special, its numeric value is simply: mantissa * 10^exponent. So, we have: 364*10^-1 = 36.4, as your example shows.

Your second example is similar. The exponent is 0xFE, and that's the number -2 in 2's complement. The mantissa is 0x000D97, which is 3479 in decimal. Again, the exponent isn't 0, so no special processing is needed. So you have: 3479*10^-2 = 34.79.

You say for the 98.5 value, you get the byte-array [113, 14, 0, 254]. Let's see if we can make sense of that. Your byte array, written in hex is: [0x71, 0x0E, 0x00, 0xFE]. I'm guessing you receive these bytes in the "reverse" order, so as a 32-bit hexadecimal this is actually 0xFE000E71.

We proceed similarly: Exponent is again -2, since 0xFE is how you write -2 in 2's complement using 8-bits. (See above.) Mantissa is 0xE71 which equals 3697. So, the number is 3697*10^-2 = 36.97.

You are claiming that this is actually 98.5. My best guess is that you are reading it in Fahrenheit, and your device is reporting in Celcius. If you do the math, you'll find that 36.97C = 98.55F, which is close enough. I'm not sure how you got the 98.5 number, but with devices like this, this outcome seems to be within the precision you can about expect.

Hope this helps!


Solution 2: Kiran Ruth R

Here is something that I used to convert sfloat16 to double in dart for our flutter app.

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);  
}