Lumiera  0.pre.03
»edit your freedom«
util-floordiv-test.cpp
Go to the documentation of this file.
1 /*
2  UtilFloordiv(Test) - verify integer rounding function
3 
4  Copyright (C) Lumiera.org
5  2011, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 * *****************************************************/
22 
28 #include "lib/test/run.hpp"
29 #include "lib/util-quant.hpp"
30 #include "lib/util.hpp"
31 
32 #include "lib/format-cout.hpp"
33 #include "lib/format-string.hpp"
34 
35 #include <cmath>
36 #include <time.h>
37 #include <vector>
38 
39 using ::Test;
40 using std::rand;
41 using util::isnil;
42 using util::_Fmt;
43 
44 
45 namespace util {
46 namespace test {
47 
48 
49 
50  namespace{ // Test data and operations
51 
52  const uint NUM_ELMS_PERFORMANCE_TEST = 50000000;
53  const uint NUMBER_LIMIT = 1 << 30;
54 
55  typedef std::vector<int> VecI;
56 
57  VecI
58  buildTestNumberz (uint cnt)
59  {
60  VecI data;
61  for (uint i=0; i<cnt; ++i)
62  {
63  int someNumber (rand() % (2*NUMBER_LIMIT) -NUMBER_LIMIT);
64  if (!someNumber) someNumber -=(1 +rand() % NUMBER_LIMIT);
65 
66  data.push_back (someNumber);
67  }
68  return data;
69  }
70 
71 
75  inline long
76  integerDiv (long num, long den)
77  {
78  return num / den;
79  }
80 
81 
85  inline long
86  floordiv_alternate (long num, long den)
87  {
88  ldiv_t res = ldiv(num,den);
89  return (0 >= res.quot && res.rem)? res.quot-1
90  : res.quot;
91  }
92 
93  } // (End) test data and operations
94 
95 
96 
97  /******************************************************************/
113  class UtilFloordiv_test : public Test
114  {
115 
116  virtual void
117  run (Arg arg)
118  {
119  verifyBehaviour ();
120 
121  verifyIntegerTypes<int>();
122  verifyIntegerTypes<long>();
123  verifyIntegerTypes<short>();
124  verifyIntegerTypes<int64_t>();
125  verifyIntegerTypes<long long int>();
126 
127  if (!isnil (arg))
129  }
130 
131 
132  void
133  verifyBehaviour ()
134  {
135  CHECK ( 3 == floordiv ( 12,4));
136  CHECK ( 2 == floordiv ( 11,4));
137  CHECK ( 2 == floordiv ( 10,4));
138  CHECK ( 2 == floordiv ( 9,4));
139  CHECK ( 2 == floordiv ( 8,4));
140  CHECK ( 1 == floordiv ( 7,4));
141  CHECK ( 1 == floordiv ( 6,4));
142  CHECK ( 1 == floordiv ( 5,4));
143  CHECK ( 1 == floordiv ( 4,4));
144  CHECK ( 0 == floordiv ( 3,4));
145  CHECK ( 0 == floordiv ( 2,4));
146  CHECK ( 0 == floordiv ( 1,4));
147  CHECK ( 0 == floordiv ( 0,4));
148  CHECK (-1 == floordiv (- 1,4));
149  CHECK (-1 == floordiv (- 2,4));
150  CHECK (-1 == floordiv (- 3,4));
151  CHECK (-1 == floordiv (- 4,4));
152  CHECK (-2 == floordiv (- 5,4));
153  CHECK (-2 == floordiv (- 6,4));
154  CHECK (-2 == floordiv (- 7,4));
155  CHECK (-2 == floordiv (- 8,4));
156  CHECK (-3 == floordiv (- 9,4));
157  CHECK (-3 == floordiv (-10,4));
158  CHECK (-3 == floordiv (-11,4));
159  CHECK (-3 == floordiv (-12,4));
160  }
161 
162 
163  template<typename I>
164  void
165  verifyIntegerTypes ()
166  {
167  I n,d,expectedRes;
168 
169  for (int i=-12; i <= 12; ++i)
170  {
171  n = i;
172  d = 4;
173  expectedRes = floordiv (i,4);
174  CHECK (floordiv(n,d) == expectedRes);
175  }
176  }
177 
178 
179 
215  void
217  {
218  VecI testdata = buildTestNumberz (2*NUM_ELMS_PERFORMANCE_TEST);
219  typedef VecI::const_iterator I;
220 
221  clock_t start(0), stop(0);
222  _Fmt resultDisplay{"timings(%s)%|30T.|%5.3fsec\n"};
223 
224 #define START_TIMINGS start=clock();
225 #define DISPLAY_TIMINGS(ID) \
226  stop = clock(); \
227  cout << resultDisplay % STRINGIFY (ID) % (double(stop-start)/CLOCKS_PER_SEC) ;
228 
229  START_TIMINGS
230  for (I ii =testdata.begin(); ii!=testdata.end(); )
231  {
232  int num = *ii;
233  ++ii;
234  int den = *ii;
235  ++ii;
236  CHECK (floor(double(num)/den) == floordiv(num,den));
237  }
238  DISPLAY_TIMINGS (Verification)
239 
240  START_TIMINGS
241  for (I ii =testdata.begin(); ii!=testdata.end(); )
242  {
243  integerDiv (*ii++, *ii++);
244  }
245  DISPLAY_TIMINGS (Integer_div)
246 
247  START_TIMINGS
248  for (I ii =testdata.begin(); ii!=testdata.end(); )
249  {
250  floor (double(*ii++) / *ii++);
251  }
252  DISPLAY_TIMINGS (double_floor)
253 
254  START_TIMINGS
255  for (I ii =testdata.begin(); ii!=testdata.end(); )
256  {
257  floordiv (*ii++, *ii++);
258  }
259  DISPLAY_TIMINGS (floordiv_int)
260 
261  START_TIMINGS
262  for (I ii =testdata.begin(); ii!=testdata.end(); )
263  {
264  floordiv (long(*ii++), long(*ii++));
265  }
266  DISPLAY_TIMINGS (floordiv_long)
267 
268  START_TIMINGS
269  for (I ii =testdata.begin(); ii!=testdata.end(); )
270  {
271  floordiv (int64_t(*ii++), int64_t(*ii++));
272  }
273  DISPLAY_TIMINGS (floordiv_int64_t)
274 
275  START_TIMINGS
276  for (I ii =testdata.begin(); ii!=testdata.end(); )
277  {
278  floordiv_alternate (*ii++, *ii++);
279  }
280  DISPLAY_TIMINGS (floordiv_long_alt)
281  }
282  };
283 
284 
285 
286 
287  LAUNCHER (UtilFloordiv_test, "unit common");
288 
289 
290 }} // namespace util::test
I floordiv(I num, I den)
floor function for integer arithmetics.
Definition: util-quant.hpp:99
Automatically use custom string conversion in C++ stream output.
Common functions for handling of time values.
Definition: run.hpp:49
Front-end for printf-style string template interpolation.
A front-end for using printf-style formatting.
Simple test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
long integerDiv(long num, long den)
the built-in integer division operator, packaged as inline function for timing comparison ...
Utilities for quantisation (grid alignment) and comparisons.
long floordiv_alternate(long num, long den)
an alternate formulation, which turned out to perform slightly worse