diff --git a/buffer.c b/buffer.c index e3cef895..59b31842 100644 --- a/buffer.c +++ b/buffer.c @@ -94,6 +94,12 @@ void buffer_append_float32(uint8_t* buffer, float number, float scale, int32_t * * floating point numbers in a fully defined manner. */ void buffer_append_float32_auto(uint8_t* buffer, float number, int32_t *index) { + // Set subnormal numbers to 0 as they are not handled properly + // using this method. + if (fabsf(number) < 1.5e-38) { + number = 0.0; + } + int e = 0; float sig = frexpf(number, &e); float sig_abs = fabsf(sig); diff --git a/tests/float_serialization/Makefile b/tests/float_serialization/Makefile new file mode 100644 index 00000000..1bc7bac9 --- /dev/null +++ b/tests/float_serialization/Makefile @@ -0,0 +1,32 @@ +TARGET = test +LIBS = -lm +CC = gcc +CFLAGS = -O2 -g -Wall -Wextra -Wundef -std=gnu99 -I../../ -DNO_STM32 +SOURCES = main.c ../../buffer.c +HEADERS = ../../buffer.h +OBJECTS = $(notdir $(SOURCES:.c=.o)) + +.PHONY: default all clean + +default: $(TARGET) +all: default + +%.o: %.c $(HEADERS) + $(CC) $(CFLAGS) -c $< -o $@ + +%.o: ../../%.c $(HEADERS) + $(CC) $(CFLAGS) -c $< -o $@ + +.PRECIOUS: $(TARGET) $(OBJECTS) + +$(TARGET): $(OBJECTS) + $(CC) $(OBJECTS) -Wall $(LIBS) -o $@ + +clean: + rm -f $(OBJECTS) $(TARGET) + +test2: + echo $(OBJECTS) + +run: $(TARGET) + ./$(TARGET) diff --git a/tests/float_serialization/main.c b/tests/float_serialization/main.c new file mode 100644 index 00000000..6991fde9 --- /dev/null +++ b/tests/float_serialization/main.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include + +#include "buffer.h" + +void test_read(unsigned char *data) { + int32_t ind = 0; + union { + float f; + uint32_t i; + } flt; + + float res = buffer_get_float32_auto(data, &ind); + printf("Read buffer: %g\r\n", res); + + ind = 0; + flt.i = buffer_get_uint32(data, &ind); + printf("Read typecast: %g\r\n", flt.f); +} + +int main(void) { + unsigned char data[4]; + int32_t ind = 0; + + float number = 0.5e-38; + + printf("Test with subnormal number: %g\r\n", number); + + union { + float f; + uint32_t i; + } flt; + + printf("=== Add using buffer ===\r\n"); + buffer_append_float32_auto(data, number, &ind); + ind = 0; + + test_read(data); + + printf("=== Add using typecast ===\r\n"); + flt.f = number; + ind = 0; + buffer_append_uint32(data, flt.i, &ind); + test_read(data); + + return 0; +} +