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. */
12 typedef struct {
13 float value;
14 } FloatMsg;
15 PB_BIND(DoubleMsg, FloatMsg, AUTO)
16
17 static 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
main()32 int 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 }
91