comparison.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
3  */
4 
5 #include <gtest/gtest.h>
7 
8 TEST(Comparison, Basic)
9 {
10  // Basic same type floats
11  ASSERT_TRUE(uavcan::areClose(0.1, 0.1));
12  ASSERT_TRUE(uavcan::areClose(0.1F, 0.1F));
13  ASSERT_TRUE(uavcan::areClose(0.1L, 0.1L));
14 
15  // Basic mixed type floats
16  ASSERT_TRUE(uavcan::areClose(0.1F, 0.1));
17  ASSERT_TRUE(uavcan::areClose(0.1, 0.1F));
18  ASSERT_TRUE(uavcan::areClose(0.1F, 0.1L));
19  ASSERT_TRUE(uavcan::areClose(0.1L, 0.1F));
20  ASSERT_TRUE(uavcan::areClose(0.1, 0.1L));
21  ASSERT_TRUE(uavcan::areClose(0.1L, 0.1));
22 
23  // Basic floats
24  ASSERT_TRUE(uavcan::areClose(0x07, '\x07'));
25  ASSERT_TRUE(uavcan::areClose(123456789LL, 123456789));
26  ASSERT_TRUE(uavcan::areClose("123", std::string("123")));
27 
28  // Non-equality
29  ASSERT_FALSE(uavcan::areClose(-0.1, 0.1));
30  ASSERT_FALSE(uavcan::areClose(-0.1F, 0.0L));
31  ASSERT_FALSE(uavcan::areClose("123", std::string("12")));
32  ASSERT_FALSE(uavcan::areClose(0x07L, '\0'));
33 }
34 
35 TEST(Comparison, FloatSpecialCase)
36 {
37  ASSERT_FALSE(uavcan::areClose(0.1, std::numeric_limits<double>::infinity()));
38 
39  ASSERT_TRUE(uavcan::areClose(std::numeric_limits<float>::infinity(),
40  std::numeric_limits<long double>::infinity()));
41 
42  ASSERT_FALSE(uavcan::areClose(std::numeric_limits<float>::infinity(), -std::numeric_limits<float>::infinity()));
43 
44  ASSERT_FALSE(uavcan::areClose(std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN()));
45 }
46 
47 TEST(Comparison, FloatULP)
48 {
49  ASSERT_FALSE(uavcan::areClose(0.100000000000000001L, 0.1L));
50  ASSERT_TRUE( uavcan::areClose(0.100000000000000001, 0.1L));
51  ASSERT_TRUE( uavcan::areClose(0.100000000000000001F, 0.1L));
52 
53  // Near zero
54  ASSERT_TRUE( uavcan::areClose(0.0F, std::numeric_limits<float>::epsilon()));
55  ASSERT_TRUE( uavcan::areClose(0.0F, -std::numeric_limits<float>::epsilon()));
56  ASSERT_FALSE(uavcan::areClose(0.0F, std::numeric_limits<float>::epsilon() * 2));
57 }
58 
59 TEST(Comparison, BruteforceValidation)
60 {
61  const std::streamsize default_precision = std::cout.precision();
62  std::cout.precision(20);
63 
65 
67  {
68  const float y1 = x + std::abs(x) * (uavcan::NumericTraits<float>::epsilon() * 2); // Still equal
69  const float y2 = x + uavcan::max(std::abs(x), 1.F) * (uavcan::NumericTraits<float>::epsilon() * 20); // Nope
70 
71  if (!uavcan::areClose(y1, x))
72  {
73  std::cout << "y1=" << y1 << " y2=" << y2 << " x=" << x << std::endl;
74  ASSERT_TRUE(false);
75  }
76  if (uavcan::areClose(y2, x))
77  {
78  std::cout << "y1=" << y1 << " y2=" << y2 << " x=" << x << std::endl;
79  ASSERT_TRUE(false);
80  }
81 
82  x = y2;
83  }
84 
85  std::cout.precision(default_precision);
86 }
87 
88 
89 struct B
90 {
91  long double b;
92  B(long double val = 0.0L) : b(val) { }
93 };
94 
95 struct A
96 {
97  float a;
98  explicit A(float val = 0.0F) : a(val) { }
99 
100  bool isClose(A rhs) const
101  {
102  std::cout << "bool A::isClose(A) --> " << rhs.a << std::endl;
103  return uavcan::areClose(a, rhs.a);
104  }
105 
106  bool isClose(const B& rhs) const
107  {
108  std::cout << "bool A::isClose(const B&) --> " << rhs.b << std::endl;
109  return uavcan::areClose(a, rhs.b);
110  }
111 };
112 
113 struct C
114 {
115  long long c;
116  explicit C(long long val = 0.0L) : c(val) { }
117 
118  bool operator==(B rhs) const
119  {
120  std::cout << "bool C::operator==(B) --> " << rhs.b << std::endl;
121  return c == static_cast<long long>(rhs.b);
122  }
123 };
124 
125 TEST(Comparison, IsCloseMethod)
126 {
127  B b;
128  A a;
129  C c;
130 
131  std::cout << 1 << std::endl;
132  ASSERT_TRUE(uavcan::areClose(a, b)); // Fuzzy
133  ASSERT_TRUE(uavcan::areClose(a, A())); // Fuzzy
134  ASSERT_TRUE(uavcan::areClose(b, a)); // Fuzzy, reverse application
135  ASSERT_TRUE(uavcan::areClose(c, b)); // Exact
136 
137  std::cout << 2 << std::endl;
138 
140 
141  ASSERT_TRUE(uavcan::areClose(a, b));
142  ASSERT_TRUE(uavcan::areClose(b, a));
143  ASSERT_TRUE(a.isClose(b));
144  ASSERT_TRUE(a.isClose(A()));
145  ASSERT_TRUE(uavcan::areClose(A(), a));
146 
147  std::cout << 3 << std::endl;
148 
149  a.a = 1e-5F;
150 
151  ASSERT_FALSE(uavcan::areClose(a, b));
152  ASSERT_FALSE(uavcan::areClose(b, a));
153  ASSERT_FALSE(uavcan::areClose(A(), a));
154 
155  std::cout << 4 << std::endl;
156 
157  b.b = 1.1L;
158  c.c = 1;
159 
160  ASSERT_TRUE(uavcan::areClose(c, b)); // Round to integer
161  ASSERT_TRUE(uavcan::areClose(c, 1.0L)); // Implicit cast to B
162  ASSERT_FALSE(uavcan::areClose(c, 0.0L));
163 }
B::B
B(long double val=0.0L)
Definition: comparison.cpp:92
TEST
TEST(Comparison, Basic)
Definition: comparison.cpp:8
B
Definition: comparison.cpp:89
C::operator==
bool operator==(B rhs) const
Definition: comparison.cpp:118
A::isClose
bool isClose(A rhs) const
Definition: comparison.cpp:100
uavcan::areClose
UAVCAN_EXPORT bool areClose(const L &left, const R &right)
Definition: comparison.hpp:158
A::isClose
bool isClose(const B &rhs) const
Definition: comparison.cpp:106
uavcan::NumericTraits< float >::epsilon
static float epsilon()
Definition: templates.hpp:461
A
Definition: comparison.cpp:95
B::b
long double b
Definition: comparison.cpp:91
A::A
A(float val=0.0F)
Definition: comparison.cpp:98
uavcan::max
const UAVCAN_EXPORT T & max(const T &a, const T &b)
Definition: templates.hpp:291
C
Definition: comparison.cpp:113
C::c
long long c
Definition: comparison.cpp:115
comparison.hpp
A::a
float a
Definition: comparison.cpp:97
C::C
C(long long val=0.0L)
Definition: comparison.cpp:116
uavcan::NumericTraits< float >::max
static float max()
Definition: templates.hpp:458
pyuavcan_v0.driver.timestamp_estimator.x
x
Definition: timestamp_estimator.py:221


uavcan_communicator
Author(s):
autogenerated on Fri Dec 13 2024 03:10:02