MOS Source Code
Loading...
Searching...
No Matches
float_double_conversion.c
Go to the documentation of this file.
1#define _USE_MATH_DEFINES 1
2#undef __STRICT_ANSI__
3#include <math.h>
4#include <stdio.h>
5#include <string.h>
6#include <pb_decode.h>
7#include <pb_encode.h>
8#include "doublemsg.pb.h"
9#include "unittests.h"
10
11/* This message mimics how DoubleMsg would appear on e.g. AVR. */
12typedef struct {
13 float value;
14} FloatMsg;
15PB_BIND(DoubleMsg, FloatMsg, AUTO)
16
17static const double testvalues[] = {
18 0.0, -0.0, 0.1, -0.1,
19 M_PI, -M_PI, 123456.789, -123456.789,
20#if defined(NAN) && defined(INFINITY)
21 INFINITY, -INFINITY, NAN, INFINITY - INFINITY,
22#endif
23 1e38, -1e38, 1e39, -1e39,
24 1e-38, -1e-38, 1e-39, -1e-39,
25 3.14159e-37,-3.14159e-37, 3.14159e-43, -3.14159e-43,
26 1e-60, -1e-60, 1e-45, -1e-45,
27 0.99999999999999, -0.99999999999999, 127.999999999999, -127.999999999999
28};
29
30#define TESTVALUES_COUNT (sizeof(testvalues)/sizeof(testvalues[0]))
31
32int main()
33{
34 uint8_t buf[16];
35 size_t msglen;
36 int status = 0;
37 int i;
38 for (i = 0; i < TESTVALUES_COUNT; i++)
39 {
40 double orig_double = testvalues[i];
41 float expected_float = (float)orig_double;
42 double expected_double = (double)expected_float;
43
44 printf("\n---- Testcase: %f ----\n", expected_float);
45
46 {
47 /* Encode the original double */
48 pb_ostream_t stream = pb_ostream_from_buffer(buf, sizeof(buf));
49 DoubleMsg msg = { 0.0 };
50 msg.value = orig_double;
51 TEST(pb_encode(&stream, &DoubleMsg_msg, &msg));
52 msglen = stream.bytes_written;
53 TEST(msglen == 9);
54 }
55
56 {
57 /* Decode as float */
58 pb_ostream_t ostream;
59 pb_istream_t stream = pb_istream_from_buffer(buf, msglen);
60 FloatMsg msg = { 0.0f };
61 TEST(pb_decode(&stream, &FloatMsg_msg, &msg));
62 TEST(memcmp(&msg.value, &expected_float, sizeof(float)) == 0);
63
64 /* Re-encode */
65 ostream = pb_ostream_from_buffer(buf, sizeof(buf));
66 TEST(pb_encode(&ostream, &FloatMsg_msg, &msg));
67 msglen = ostream.bytes_written;
68 TEST(msglen == 9);
69 }
70
71 {
72 /* Decode as double */
73 pb_istream_t stream = pb_istream_from_buffer(buf, msglen);
74 DoubleMsg msg = { 0.0 };
75 TEST(pb_decode(&stream, &DoubleMsg_msg, &msg));
76
77 if (isnan(expected_double))
78 {
79 /* Bottom bits of NAN converted to double can vary */
80 TEST(isnan(msg.value));
81 }
82 else
83 {
84 TEST(memcmp(&msg.value, &expected_double, sizeof(double)) == 0);
85 }
86 }
87 }
88
89 return status;
90}
static const double testvalues[]
#define TESTVALUES_COUNT
MOSAPI int memcmp(const void *s1, const void *s2, size_t n)
Definition mos_string.c:142
#define PB_BIND(msgname, structname, width)
Definition pb.h:505
bool pb_decode(pb_istream_t *stream, const pb_msgdesc_t *fields, void *dest_struct)
Definition pb_decode.c:1182
pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t msglen)
Definition pb_decode.c:143
pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize)
Definition pb_encode.c:63
bool pb_encode(pb_ostream_t *stream, const pb_msgdesc_t *fields, const void *src_struct)
Definition pb_encode.c:512
unsigned char uint8_t
Definition pb_syshdr.h:20
#define TEST(x)
Definition test.h:3