PX4 Firmware
PX4 Autopilot Software http://px4.io
test_float.cpp
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright (C) 2012-2019 PX4 Development Team. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * 3. Neither the name PX4 nor the names of its contributors may be
16  * used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  *
32  ****************************************************************************/
33 
34 /**
35  * @file test_float.cpp
36  * Tests for floating point arithmetic.
37  */
38 
39 #include <unit_test.h>
40 
41 #include <px4_platform_common/px4_config.h>
42 
43 #include <float.h>
44 #include <math.h>
45 
46 typedef union {
47  float f;
48  double d;
49  uint8_t b[8];
51 
52 
53 
54 class FloatTest : public UnitTest
55 {
56 public:
57  virtual bool run_tests();
58 
59 private:
60  bool singlePrecisionTests();
61  bool doublePrecisionTests();
62 };
63 
65 {
66  float sinf_zero = sinf(0.0f);
67  float sinf_one = sinf(1.0f);
68  float sqrt_two = sqrtf(2.0f);
69 
70  ut_assert("sinf(0.0f) == 0.0f", fabsf(sinf_zero) < FLT_EPSILON);
71  ut_assert("sinf(1.0f) == 0.84147f", fabsf((sinf_one - 0.841470956802368164062500000000f)) < FLT_EPSILON);
72 
73  float asinf_one = asinf(1.0f);
74  ut_assert("asinf(1.0f) == 1.57079f", fabsf((asinf_one - 1.570796251296997070312500000000f)) < FLT_EPSILON * 1.5f);
75 
76  float cosf_one = cosf(1.0f);
77  ut_assert("cosf(1.0f) == 0.54030f", fabsf((cosf_one - 0.540302336215972900390625000000f)) < FLT_EPSILON);
78 
79  float acosf_one = acosf(1.0f);
80  ut_assert("acosf(1.0f) == 0.0f", fabsf((acosf_one - 0.000000000000000000000000000000f)) < FLT_EPSILON);
81 
82  float sinf_zero_one = sinf(0.1f);
83  ut_assert("sinf(0.1f) == 0.09983f", fabsf(sinf_zero_one - 0.0998334166f) < FLT_EPSILON);
84 
85  ut_assert("sqrt(2.0f) == 1.41421f", fabsf(sqrt_two - 1.41421356f) < FLT_EPSILON);
86 
87  float atan2f_ones = atan2f(1.0f, 1.0f);
88  ut_assert("atan2f(1.0f, 1.0f) == 0.78539f",
89  fabsf(atan2f_ones - 0.785398163397448278999490867136f) < 2.0f * FLT_EPSILON);
90 
91  char sbuf[30];
92  sprintf(sbuf, "%8.4f", (double)0.553415f);
93  ut_compare("sbuf[0]", sbuf[0], ' ');
94  ut_compare("sbuf[1]", sbuf[1], ' ');
95  ut_compare("sbuf[2]", sbuf[2], '0');
96  ut_compare("sbuf[3]", sbuf[3], '.');
97  ut_compare("sbuf[4]", sbuf[4], '5');
98  ut_compare("sbuf[5]", sbuf[5], '5');
99  ut_compare("sbuf[6]", sbuf[6], '3');
100  ut_compare("sbuf[7]", sbuf[7], '4');
101  ut_compare("sbuf[8]", sbuf[8], '\0');
102 
103  sprintf(sbuf, "%8.4f", (double) - 0.553415f);
104  ut_compare("sbuf[0]", sbuf[0], ' ');
105  ut_compare("sbuf[1]", sbuf[1], '-');
106  ut_compare("sbuf[2]", sbuf[2], '0');
107  ut_compare("sbuf[3]", sbuf[3], '.');
108  ut_compare("sbuf[4]", sbuf[4], '5');
109  ut_compare("sbuf[5]", sbuf[5], '5');
110  ut_compare("sbuf[6]", sbuf[6], '3');
111  ut_compare("sbuf[7]", sbuf[7], '4');
112  ut_compare("sbuf[8]", sbuf[8], '\0');
113 
114  return true;
115 }
116 
117 
119 {
120  float f1 = 1.55f;
121 
122  double d1 = 1.0111;
123  double d2 = 2.0;
124 
125  double d1d2 = d1 * d2;
126 
127  ut_assert("1.0111 * 2.0 == 2.0222", fabs(d1d2 - 2.022200000000000219557705349871) < DBL_EPSILON);
128 
129  // Assign value of f1 to d1
130  d1 = f1;
131 
132  ut_assert("(float) 1.55f == 1.55 (double)", fabsf(f1 - (float)d1) < FLT_EPSILON);
133 
134 
135  double sin_zero = sin(0.0);
136  double sin_one = sin(1.0);
137  double atan2_ones = atan2(1.0, 1.0);
138 
139  ut_assert("sin(0.0) == 0.0", fabs(sin_zero - 0.0) < DBL_EPSILON);
140  ut_assert("sin(1.0) == 0.84147098480", fabs(sin_one - 0.841470984807896504875657228695) < DBL_EPSILON);
141  ut_assert("atan2(1.0, 1.0) == 0.785398", fabs(atan2_ones - 0.785398163397448278999490867136) < 2.0 * DBL_EPSILON);
142  ut_assert("testing pow() with magic value",
143  (44330.0 * (1.0 - pow((96286LL / 101325.0), 0.190295))) - 428.2293 < DBL_EPSILON);
144 
145 
146  char sbuf[30];
147  sprintf(sbuf, "%8.4f", 0.553415);
148  ut_compare("sbuf[0]", sbuf[0], ' ');
149  ut_compare("sbuf[1]", sbuf[1], ' ');
150  ut_compare("sbuf[2]", sbuf[2], '0');
151  ut_compare("sbuf[3]", sbuf[3], '.');
152  ut_compare("sbuf[4]", sbuf[4], '5');
153  ut_compare("sbuf[5]", sbuf[5], '5');
154  ut_compare("sbuf[6]", sbuf[6], '3');
155  ut_compare("sbuf[7]", sbuf[7], '4');
156  ut_compare("sbuf[8]", sbuf[8], '\0');
157 
158 
159  sprintf(sbuf, "%8.4f", -0.553415);
160  ut_compare("sbuf[0]", sbuf[0], ' ');
161  ut_compare("sbuf[1]", sbuf[1], '-');
162  ut_compare("sbuf[2]", sbuf[2], '0');
163  ut_compare("sbuf[3]", sbuf[3], '.');
164  ut_compare("sbuf[4]", sbuf[4], '5');
165  ut_compare("sbuf[5]", sbuf[5], '5');
166  ut_compare("sbuf[6]", sbuf[6], '3');
167  ut_compare("sbuf[7]", sbuf[7], '4');
168  ut_compare("sbuf[8]", sbuf[8], '\0');
169 
170  return true;
171 }
172 
174 {
175  ut_run_test(singlePrecisionTests);
176  ut_run_test(doublePrecisionTests);
177 
178  return (_tests_failed == 0);
179 }
180 
bool singlePrecisionTests()
Definition: test_float.cpp:64
#define ut_declare_test_c(test_function, test_class)
Definition: unit_test.h:40
Base class to be used for unit tests.
Definition: unit_test.h:54
#define FLT_EPSILON
#define ut_assert(message, test)
Used to assert a value within a unit test.
Definition: unit_test.h:113
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
Definition: integration.cpp:8
virtual bool run_tests()
Override to run your unit tests.
Definition: test_float.cpp:173
int test_float(int argc, char *argv[])
#define ut_compare(message, v1, v2)
Used to compare two integer values within a unit test.
Definition: unit_test.h:150
#define ut_run_test(test)
Runs a single unit test.
Definition: unit_test.h:96
bool doublePrecisionTests()
Definition: test_float.cpp:118
Dual< Scalar, N > sin(const Dual< Scalar, N > &a)
Definition: Dual.hpp:279
Dual< Scalar, N > atan2(const Dual< Scalar, N > &a, const Dual< Scalar, N > &b)
Definition: Dual.hpp:325