A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
int64x64-test-suite.cc
1 #include "ns3/int64x64.h"
2 #include "ns3/test.h"
3 
4 using namespace ns3;
5 
7 {
8 public:
10  virtual void DoRun (void);
11  void CheckFrac (int64_t hi, uint64_t lo);
12 };
13 
14 void
15 Int64x64FracTestCase::CheckFrac (int64_t hi, uint64_t lo)
16 {
17  int64x64_t tmp = int64x64_t (hi,lo);
18  NS_TEST_EXPECT_MSG_EQ (tmp.GetHigh (), hi,
19  "High part does not match");
20  NS_TEST_EXPECT_MSG_EQ (tmp.GetLow (), lo,
21  "Low part does not match");
22 }
23 
24 Int64x64FracTestCase::Int64x64FracTestCase ()
25  : TestCase ("Check that we can manipulate the high and low part of every number")
26 {
27 }
28 void
30 {
31  CheckFrac (1, 0);
32  CheckFrac (1, 1);
33  CheckFrac (-1, 0);
34  CheckFrac (-1, 1);
35 }
36 
37 
39 {
40 public:
42  virtual void DoRun (void);
43  void CheckString (std::string str, int64_t hi, uint64_t lo);
44 };
45 Int64x64InputTestCase::Int64x64InputTestCase ()
46  : TestCase ("Check that we parse Int64x64 numbers as strings")
47 {
48 }
49 void
50 Int64x64InputTestCase::CheckString (std::string str, int64_t hi, uint64_t lo)
51 {
52  std::istringstream iss;
53  iss.str (str);
54  int64x64_t hp;
55  iss >> hp;
56  NS_TEST_EXPECT_MSG_EQ (hp.GetHigh (), hi, "High parts do not match for input string " << str);
57  NS_TEST_EXPECT_MSG_EQ (hp.GetLow (), lo, "Low parts do not match for input string " << str);
58 }
59 void
61 {
62  CheckString ("1", 1, 0);
63  CheckString ("+1", 1, 0);
64  CheckString ("-1", -1, 0);
65  CheckString ("1.0", 1, 0);
66  CheckString ("+1.0", 1, 0);
67  CheckString ("001.0", 1, 0);
68  CheckString ("+001.0", 1, 0);
69  CheckString ("020.0", 20, 0);
70  CheckString ("+020.0", 20, 0);
71  CheckString ("-1.0", -1, 0);
72  CheckString ("-1.0000", -1, 0);
73  CheckString ("1.0000000", 1, 0);
74  CheckString ("1.08446744073709551615", 1, 8446744073709551615LL);
75  CheckString ("-1.08446744073709551615", -1, 8446744073709551615LL);
76 }
77 
79 {
80 public:
82  virtual void DoRun (void);
83  void CheckString (std::string str);
84 };
85 Int64x64InputOutputTestCase::Int64x64InputOutputTestCase ()
86  : TestCase ("Check that we can roundtrip Int64x64 numbers as strings")
87 {
88 }
89 void
90 Int64x64InputOutputTestCase::CheckString (std::string str)
91 {
92  std::istringstream iss;
93  iss.str (str);
94  int64x64_t value;
95  iss >> value;
96  std::ostringstream oss;
97  oss << value;
98  NS_TEST_EXPECT_MSG_EQ (oss.str (), str, "Converted string does not match expected string");
99 }
100 void
102 {
103  CheckString ("+1.0");
104  CheckString ("-1.0");
105  CheckString ("+20.0");
106  CheckString ("+1.08446744073709551615");
107  CheckString ("-1.08446744073709551615");
108  CheckString ("+1.18446744073709551615");
109  CheckString ("-1.18446744073709551615");
110 }
111 
112 #define CHECK_EXPECTED(a,b) \
113  NS_TEST_ASSERT_MSG_EQ ((a).GetHigh (),b,"Arithmetic failure: " << ((a).GetHigh ()) << "!=" << (b))
114 
115 #define V(v) \
116  int64x64_t (v)
117 
119 {
120 public:
122  virtual void DoRun (void);
123 };
124 
125 Int64x64ArithmeticTestCase::Int64x64ArithmeticTestCase ()
126  : TestCase ("Check basic arithmetic operations")
127 {
128 }
129 void
131 {
132  int64x64_t a, b;
133 
134  CHECK_EXPECTED (V (1) - V (1), 0);
135  CHECK_EXPECTED (V (1) - V (2), -1);
136  CHECK_EXPECTED (V (1) - V (3), -2);
137  CHECK_EXPECTED (V (1) - V (-1), 2);
138  CHECK_EXPECTED (V (1) - V (-2), 3);
139  CHECK_EXPECTED (V (-3) - V (-4), 1);
140  CHECK_EXPECTED (V (-2) - V (3), -5);
141  CHECK_EXPECTED (V (1) + V (2), 3);
142  CHECK_EXPECTED (V (1) + V (-3), -2);
143  CHECK_EXPECTED (V (0) + V (0), 0);
144  CHECK_EXPECTED (V (0) * V (0), 0);
145  CHECK_EXPECTED (V (0) * V (1), 0);
146  CHECK_EXPECTED (V (0) * V (-1), 0);
147  CHECK_EXPECTED (V (1) * V (0), 0);
148  CHECK_EXPECTED (V (1) * V (1), 1);
149  CHECK_EXPECTED (V (1) * V (-1), -1);
150  CHECK_EXPECTED (V (-1) * V (-1), 1);
151  CHECK_EXPECTED (V (0) * V (1), 0);
152  CHECK_EXPECTED (V (0) * V (-1), 0);
153  CHECK_EXPECTED (V (-1) * V (1), -1);
154 
155 
156  CHECK_EXPECTED (V (2) * V (3) / V (3), 2);
157 
158  // Below, the division loses precision because 2/3 is not
159  // representable exactly in 64.64 integers. So, we got
160  // something super close but the final rounding kills us.
161  a = V (2);
162  b = V (3);
163  a /= b;
164  a *= b;
165  CHECK_EXPECTED (V (2) / V (3) * V (3), 1);
166 
167  // The example below shows that we really do not lose
168  // much precision internally: it is almost always the
169  // final conversion which loses precision.
170  CHECK_EXPECTED (V (2000000000) / V (3) * V (3), 1999999999);
171 }
172 
174 {
175 public:
177  virtual void DoRun (void);
178 };
179 
180 Int64x64Bug455TestCase::Int64x64Bug455TestCase ()
181  : TestCase ("Test case for bug 455")
182 {
183 }
184 void
186 {
187  int64x64_t a = int64x64_t (0.1);
188  a /= int64x64_t (1.25);
189  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), 0.08, "The original testcase");
190  a = int64x64_t (0.5);
191  a *= int64x64_t (5);
192  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), 2.5, "Simple test for multiplication");
193  a = int64x64_t (-0.5);
194  a *= int64x64_t (5);
195  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), -2.5, "Test sign, first operation negative");
196  a = int64x64_t (-0.5);
197  a *=int64x64_t (-5);
198  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), 2.5, "both operands negative");
199  a = int64x64_t (0.5);
200  a *= int64x64_t (-5);
201  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), -2.5, "only second operand negative");
202 }
203 
205 {
206 public:
208  virtual void DoRun (void);
209 };
210 
211 Int64x64Bug863TestCase::Int64x64Bug863TestCase ()
212  : TestCase ("Test case for bug 863")
213 {
214 }
215 void
217 {
218  int64x64_t a = int64x64_t (0.9);
219  a /= int64x64_t (1);
220  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), 0.9, "The original testcase");
221  a = int64x64_t (0.5);
222  a /= int64x64_t (0.5);
223  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), 1.0, "Simple test for division");
224  a = int64x64_t (-0.5);
225  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), -0.5, "Check that we actually convert doubles correctly");
226  a /= int64x64_t (0.5);
227  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), -1.0, "first argument negative");
228  a = int64x64_t (0.5);
229  a /= int64x64_t (-0.5);
230  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), -1.0, "second argument negative");
231  a = int64x64_t (-0.5);
232  a /= int64x64_t (-0.5);
233  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), 1.0, "both arguments negative");
234 }
235 
237 {
238 public:
240  virtual void DoRun (void);
241 };
242 Int64x64CompareTestCase::Int64x64CompareTestCase ()
243  : TestCase ("Check basic compare operations")
244 {
245 }
246 void
248 {
249 
250  NS_TEST_ASSERT_MSG_EQ ((V (-1) < V (1)), true, "a is smaller than b");
251  NS_TEST_ASSERT_MSG_EQ ((V (-1) > V (-2)), true, "a is bigger than b");
252  NS_TEST_ASSERT_MSG_EQ ((V (-1) == V (-1)), true, "a is equal to b");
253 
254  NS_TEST_ASSERT_MSG_EQ ((V (1) > V (-1)), true, "a is bigger than b");
255  NS_TEST_ASSERT_MSG_EQ ((V (1) < V (2)), true, "a is smaller than b");
256 }
257 
259 {
260 public:
262  virtual void DoRun (void);
263 };
264 
265 Int64x64InvertTestCase::Int64x64InvertTestCase ()
266  : TestCase ("Test case for invertion")
267 {
268 }
269 
270 void
272 {
273 #define TEST(factor) \
274  do { \
275  int64x64_t a; \
276  a = int64x64_t::Invert (factor); \
277  int64x64_t b = V (factor); \
278  b.MulByInvert (a); \
279  NS_TEST_ASSERT_MSG_EQ (b.GetHigh (), 1, \
280  "x * 1/x should be 1 for x=" << factor); \
281  int64x64_t c = V (1); \
282  c.MulByInvert (a); \
283  NS_TEST_ASSERT_MSG_EQ (c.GetHigh (), 0, \
284  "1 * 1/x should be 0 for x=" << factor); \
285  int64x64_t d = V (1); \
286  d /= (V (factor)); \
287  NS_TEST_ASSERT_MSG_EQ (d.GetDouble (), c.GetDouble (), \
288  "1 * 1/x should be equal to 1/x for x=" << factor); \
289  int64x64_t e = V (-factor); \
290  e.MulByInvert (a); \
291  NS_TEST_ASSERT_MSG_EQ (e.GetHigh (), -1, \
292  "-x * 1/x should be -1 for x=" << factor); \
293  } \
294  while(false)
295  TEST (2);
296  TEST (3);
297  TEST (4);
298  TEST (5);
299  TEST (6);
300  TEST (10);
301  TEST (99);
302  TEST (100);
303  TEST (1000);
304  TEST (10000);
305  TEST (100000);
306  TEST (100000);
307  TEST (1000000);
308  TEST (10000000);
309  TEST (100000000);
310  TEST (1000000000);
311  TEST (10000000000LL);
312  TEST (100000000000LL);
313  TEST (1000000000000LL);
314  TEST (10000000000000LL);
315  TEST (100000000000000LL);
316  TEST (1000000000000000LL);
317 #undef TEST
318 }
319 
320 
321 
322 static class Int64x64128TestSuite : public TestSuite
323 {
324 public:
326  : TestSuite ("int64x64", UNIT)
327  {
328  AddTestCase (new Int64x64FracTestCase (), TestCase::QUICK);
329  AddTestCase (new Int64x64InputTestCase (), TestCase::QUICK);
330  AddTestCase (new Int64x64InputOutputTestCase (), TestCase::QUICK);
331  AddTestCase (new Int64x64ArithmeticTestCase (), TestCase::QUICK);
332  AddTestCase (new Int64x64Bug455TestCase (), TestCase::QUICK);
333  AddTestCase (new Int64x64Bug863TestCase (), TestCase::QUICK);
334  AddTestCase (new Int64x64CompareTestCase (), TestCase::QUICK);
335  AddTestCase (new Int64x64InvertTestCase (), TestCase::QUICK);
336  }
337 } g_int64x64TestSuite;
virtual void DoRun(void)
Implementation to actually run this test case.
virtual void DoRun(void)
Implementation to actually run this test case.
A suite of tests to run.
Definition: test.h:962
virtual void DoRun(void)
Implementation to actually run this test case.
encapsulates test code
Definition: test.h:834
virtual void DoRun(void)
Implementation to actually run this test case.
virtual void DoRun(void)
Implementation to actually run this test case.
TestSuite(std::string name, Type type=UNIT)
Constuct a new test suite.
Definition: test.cc:354
virtual void DoRun(void)
Implementation to actually run this test case.
void AddTestCase(TestCase *testCase) NS_DEPRECATED
Add an individual test case to this test suite.
Definition: test.cc:172
virtual void DoRun(void)
Implementation to actually run this test case.
virtual void DoRun(void)
Implementation to actually run this test case.