Skip to content

Commit 5742d1b

Browse files
committed
Handle subnormal numbers in float serialization
1 parent 93fa359 commit 5742d1b

File tree

3 files changed

+89
-0
lines changed

3 files changed

+89
-0
lines changed

buffer.c

+6
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,12 @@ void buffer_append_float32(uint8_t* buffer, float number, float scale, int32_t *
9494
* floating point numbers in a fully defined manner.
9595
*/
9696
void buffer_append_float32_auto(uint8_t* buffer, float number, int32_t *index) {
97+
// Set subnormal numbers to 0 as they are not handled properly
98+
// using this method.
99+
if (fabsf(number) < 1.5e-38) {
100+
number = 0.0;
101+
}
102+
97103
int e = 0;
98104
float sig = frexpf(number, &e);
99105
float sig_abs = fabsf(sig);

tests/float_serialization/Makefile

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
TARGET = test
2+
LIBS = -lm
3+
CC = gcc
4+
CFLAGS = -O2 -g -Wall -Wextra -Wundef -std=gnu99 -I../../ -DNO_STM32
5+
SOURCES = main.c ../../buffer.c
6+
HEADERS = ../../buffer.h
7+
OBJECTS = $(notdir $(SOURCES:.c=.o))
8+
9+
.PHONY: default all clean
10+
11+
default: $(TARGET)
12+
all: default
13+
14+
%.o: %.c $(HEADERS)
15+
$(CC) $(CFLAGS) -c $< -o $@
16+
17+
%.o: ../../%.c $(HEADERS)
18+
$(CC) $(CFLAGS) -c $< -o $@
19+
20+
.PRECIOUS: $(TARGET) $(OBJECTS)
21+
22+
$(TARGET): $(OBJECTS)
23+
$(CC) $(OBJECTS) -Wall $(LIBS) -o $@
24+
25+
clean:
26+
rm -f $(OBJECTS) $(TARGET)
27+
28+
test2:
29+
echo $(OBJECTS)
30+
31+
run: $(TARGET)
32+
./$(TARGET)

tests/float_serialization/main.c

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <stdbool.h>
4+
#include <string.h>
5+
#include <math.h>
6+
7+
#include "buffer.h"
8+
9+
void test_read(unsigned char *data) {
10+
int32_t ind = 0;
11+
union {
12+
float f;
13+
uint32_t i;
14+
} flt;
15+
16+
float res = buffer_get_float32_auto(data, &ind);
17+
printf("Read buffer: %g\r\n", res);
18+
19+
ind = 0;
20+
flt.i = buffer_get_uint32(data, &ind);
21+
printf("Read typecast: %g\r\n", flt.f);
22+
}
23+
24+
int main(void) {
25+
unsigned char data[4];
26+
int32_t ind = 0;
27+
28+
float number = 0.5e-38;
29+
30+
printf("Test with subnormal number: %g\r\n", number);
31+
32+
union {
33+
float f;
34+
uint32_t i;
35+
} flt;
36+
37+
printf("=== Add using buffer ===\r\n");
38+
buffer_append_float32_auto(data, number, &ind);
39+
ind = 0;
40+
41+
test_read(data);
42+
43+
printf("=== Add using typecast ===\r\n");
44+
flt.f = number;
45+
ind = 0;
46+
buffer_append_uint32(data, flt.i, &ind);
47+
test_read(data);
48+
49+
return 0;
50+
}
51+

0 commit comments

Comments
 (0)