Added support for 4 byte floating point numbers

This commit is contained in:
Stefan Wahren 2012-04-06 17:42:55 +02:00
parent c965daf3c7
commit 1f2695d428
2 changed files with 61 additions and 1 deletions

View File

@ -10,6 +10,7 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#include <assert.h> #include <assert.h>
#include <math.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -438,6 +439,53 @@ mbus_data_int_encode(u_char *int_data, size_t int_data_size, int value)
return -1; return -1;
} }
//------------------------------------------------------------------------------
///
/// Decode float data
///
/// see also http://en.wikipedia.org/wiki/Single-precision_floating-point_format
///
//------------------------------------------------------------------------------
float
mbus_data_float_decode(u_char *float_data)
{
float val = 0.0f;
long temp = 0, fraction;
int sign,exponent;
size_t i;
if (float_data)
{
for (i = 4; i > 0; i--)
{
temp = (temp << 8) + float_data[i-1];
}
// first bit = sign bit
sign = (temp >> 31) ? -1 : 1;
// decode 8 bit exponent
exponent = ((temp & 0x7F800000) >> 23) - 127;
// decode explicit 23 bit fraction
fraction = temp & 0x007FFFFF;
if ((exponent != -127) &&
(exponent != 128))
{
// normalized value, add bit 24
fraction |= 0x800000;
}
// calculate float value
val = (float) sign * fraction * pow(2.0f, -23.0f) * (1 << exponent);
return val;
}
return -1.0;
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/// ///
/// Decode string data. /// Decode string data.
@ -1626,6 +1674,7 @@ mbus_data_record_decode(mbus_data_record *record)
{ {
int val; int val;
long val2; long val2;
float val3;
struct tm time; struct tm time;
switch (record->drh.dib.dif & 0x0F) switch (record->drh.dib.dif & 0x0F)
@ -1710,7 +1759,16 @@ mbus_data_record_decode(mbus_data_record *record)
break; break;
// case 0x05: case 0x05: // 4 Byte Real (32 bit)
val3 = mbus_data_float_decode(record->data);
snprintf(buff, sizeof(buff), "%f", val3);
if (debug)
printf("%s: DIF 0x%.2x was decoded using 4 byte Real\n", __PRETTY_FUNCTION__, record->drh.dib.dif);
break;
case 0x06: // 6 byte integer (48 bit) case 0x06: // 6 byte integer (48 bit)

View File

@ -512,6 +512,8 @@ long mbus_data_bcd_decode(u_char *bcd_data, size_t bcd_data_size);
int mbus_data_int_decode(u_char *int_data, size_t int_data_size); int mbus_data_int_decode(u_char *int_data, size_t int_data_size);
long mbus_data_long_decode(u_char *int_data, size_t int_data_size); long mbus_data_long_decode(u_char *int_data, size_t int_data_size);
float mbus_data_float_decode(u_char *float_data);
void mbus_data_tm_decode(struct tm *t, u_char *t_data, size_t t_data_size); void mbus_data_tm_decode(struct tm *t, u_char *t_data, size_t t_data_size);
void mbus_data_str_decode(u_char *dst, const u_char *src, size_t len); void mbus_data_str_decode(u_char *dst, const u_char *src, size_t len);