From 7e1be93dbd00c3e966b9be2d3e13c75a2c257500 Mon Sep 17 00:00:00 2001 From: jakubovsky Date: Tue, 21 Aug 2012 06:08:23 +0200 Subject: [PATCH 1/3] Needless IEEE754 conversion, float pointer cast instead --- mbus/mbus-protocol.c | 35 ++--------------------------------- 1 file changed, 2 insertions(+), 33 deletions(-) diff --git a/mbus/mbus-protocol.c b/mbus/mbus-protocol.c index 5b80537..a032786 100755 --- a/mbus/mbus-protocol.c +++ b/mbus/mbus-protocol.c @@ -649,41 +649,10 @@ mbus_data_int_encode(unsigned char *int_data, size_t int_data_size, int value) float mbus_data_float_decode(unsigned 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]; - } + return *(float *) float_data; - // 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 + exponent); - - return val; - } - - return -1.0; + return -1.0f; } //------------------------------------------------------------------------------ From 583a397e8e712df941e29c0cef4cbd9429deff18 Mon Sep 17 00:00:00 2001 From: jakubovsky Date: Tue, 21 Aug 2012 06:56:36 +0200 Subject: [PATCH 2/3] Needless math.h include --- mbus/mbus-protocol.c | 1 - 1 file changed, 1 deletion(-) diff --git a/mbus/mbus-protocol.c b/mbus/mbus-protocol.c index a032786..c0a4c37 100755 --- a/mbus/mbus-protocol.c +++ b/mbus/mbus-protocol.c @@ -10,7 +10,6 @@ #include #include -#include #include #include From ef6c4be655c9ad1e4faa627f3f7eeb061eff4e96 Mon Sep 17 00:00:00 2001 From: Stuart Longland Date: Thu, 3 Dec 2015 08:08:22 +1000 Subject: [PATCH 3/3] Safer IEEE754 conversion. The conversion given assumed two things: 1. the pointer was either 32-bit aligned or that unaligned word access was safe. (Not the case on ARM) We avoid this by using memcpy to copy to a buffer that *is* 32-bit-word-aligned. 2. the word was in native-endian format. The original code appeared to assume the given word would be in big-endian format (aka "network" byte order), so we convert it to the host's native format before casting. We re-instate the original implementation, controlled by a compiler switch to allow easy rollback if problems are encountered. --- mbus/mbus-protocol.c | 47 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/mbus/mbus-protocol.c b/mbus/mbus-protocol.c index c0a4c37..3ee1461 100755 --- a/mbus/mbus-protocol.c +++ b/mbus/mbus-protocol.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "mbus-protocol.h" @@ -648,8 +649,52 @@ mbus_data_int_encode(unsigned char *int_data, size_t int_data_size, int value) float mbus_data_float_decode(unsigned char *float_data) { +#ifdef _HAS_NON_IEEE754_FLOAT + float val = 0.0f; + long temp = 0, fraction; + int sign,exponent; + size_t i; + if (float_data) - return *(float *) 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 + exponent); + + return val; + } +#else + if (float_data) + { + union { + uint32_t u32; + float f; + } data; + memcpy(&(data.u32), float_data, sizeof(uint32_t)); + data.u32 = ntohl(data.u32); + return data.f; + } +#endif return -1.0f; }