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