rvm  1.11
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
test-rmath.cc
Go to the documentation of this file.
1 #include "config.h"
2 
3 #include <iostream>
4 #include <string>
5 #include <cassert>
6 
7 #ifdef HAVE_LIMITS
8 #include <limits>
9 #endif
10 #include <limits.h>
11 #include <float.h>
12 
13 #include "asserts.h"
14 #include "types.h"
15 #include "error.h"
16 #include "rmath.h"
17 
18 #define TEST(expected,code) \
19  thrown = false; \
20  try { \
21  code; \
22  } \
23  catch(error e) { \
24  thrown = true; \
25  if (thrown != expected) { \
26  std::cerr << e; \
27  } \
28  } \
29  catch(...) { \
30  assert(0); \
31  }
32 
33 void test1(void)
34 {
35  {
36  safe_num<uint8> i8;
37  bool thrown = false;
38 
39  i8 = 0;
40  TEST(false,i8 += 10);
41  assert(!thrown);
42  assert(i8 == 10);
43 
44  TEST(false,i8 += 200);
45  assert(!thrown);
46  assert(i8 == 210);
47 
48  TEST(false,i8 += 45);
49  assert(!thrown);
50  assert(i8 == 255);
51 
52  TEST(true,i8 += 1);
53  assert(thrown);
54  assert(i8 == 255);
55  }
56  {
58  bool thrown = false;
59 
60  i8 = 0;
61  TEST(false,i8 += 10);
62  assert(!thrown);
63  assert(i8 == 10);
64 
65  TEST(false,i8 += 110);
66  assert(!thrown);
67  assert(i8 == 120);
68 
69  TEST(false,i8 += 7);
70  assert(!thrown);
71  assert(i8 == 127);
72 
73  TEST(true,i8 += 1);
74  assert(thrown);
75  assert(i8 == 127);
76  }
77 }
78 
79 void test2(void)
80 {
81  safe_num<uint8> i8;
82  bool thrown = false;
83 
84  i8 = 1;
85  TEST(false,i8 *= 10);
86  assert(!thrown);
87  assert(i8 == 10);
88 
89  TEST(false,i8 *= 25);
90  assert(!thrown);
91  assert(i8 == 250);
92 
93  TEST(true,i8 *= 10);
94  assert(thrown);
95  assert(i8 == 250);
96 }
97 
98 void test3(void)
99 {
100  safe_num<uint64> n1, n2;
101  safe_num<uint64> num;
102  bool thrown = false;
103 
104  for (n1 = 0; n1 < 1250; ++n1) {
105  for (n2 = 0; n2 < 1250; ++n2) {
106  num = n1;
107  TEST(false,num = n1 * n2);
108  assert(!thrown);
109  if (num != n1 * n2)
110  std::cerr
111  << "*** ERROR: safe_num<uint64> operator*("
112  << n1
113  << ", "
114  << n2
115  << ") failed"
116  << std::endl;
117  assert(num == n1 * n2);
118  }
119  TEST(true,num = n1 * (max_limit(n2) - safe_num<uint64>(1)));
120  }
121 }
122 
123 void test4(void)
124 {
125  assert(max_limit<bool>() == true);
126  assert(min_limit<bool>() == false);
127 
128  assert(max_limit<char>() == CHAR_MAX);
129  assert(min_limit<char>() == CHAR_MIN);
130 
131  assert(max_limit<signed char>() == SCHAR_MAX);
132  assert(min_limit<signed char>() == SCHAR_MIN);
133 
134  assert(max_limit<unsigned char>() == UCHAR_MAX);
135  assert(min_limit<unsigned char>() == 0);
136 
137  assert(max_limit<short>() == SHRT_MAX);
138  assert(min_limit<short>() == SHRT_MIN);
139 
140  assert(max_limit<unsigned short>() == USHRT_MAX);
141  assert(min_limit<unsigned short>() == 0);
142 
143  assert(max_limit<int>() == INT_MAX);
144  assert(min_limit<int>() == INT_MIN);
145 
146  assert(max_limit<unsigned int>() == UINT_MAX);
147  assert(min_limit<unsigned int>() == 0);
148 
149  assert(max_limit<long>() == LONG_MAX);
150  assert(min_limit<long>() == LONG_MIN);
151 
152  assert(max_limit<unsigned long>() == ULONG_MAX);
153  assert(min_limit<unsigned long>() == 0);
154 
155  assert(max_limit<float>() == FLT_MAX);
156  assert(min_limit<float>() == FLT_MIN);
157 
158  assert(max_limit<double>() == DBL_MAX);
159  assert(min_limit<double>() == DBL_MIN);
160 
161 #ifdef HAVE_LIMITS
162  assert(max_limit<bool>() == std::numeric_limits<bool>::max());
163  assert(min_limit<bool>() == std::numeric_limits<bool>::min());
164 
165  assert(max_limit<char>() == std::numeric_limits<char>::max());
166  assert(min_limit<char>() == std::numeric_limits<char>::min());
167 
168  assert(max_limit<signed char>() == std::numeric_limits<signed char>::max());
169  assert(min_limit<signed char>() == std::numeric_limits<signed char>::min());
170 
171  assert(max_limit<unsigned char>() == std::numeric_limits<unsigned char>::max());
172  assert(min_limit<unsigned char>() == std::numeric_limits<unsigned char>::min());
173 
174  assert(max_limit<short>() == std::numeric_limits<short>::max());
175  assert(min_limit<short>() == std::numeric_limits<short>::min());
176 
177  assert(max_limit<unsigned short>() == std::numeric_limits<unsigned short>::max());
178  assert(min_limit<unsigned short>() == std::numeric_limits<unsigned short>::min());
179 
180  assert(max_limit<int>() == std::numeric_limits<int>::max());
181  assert(min_limit<int>() == std::numeric_limits<int>::min());
182 
183  assert(max_limit<unsigned int>() == std::numeric_limits<unsigned int>::max());
184  assert(min_limit<unsigned int>() == std::numeric_limits<unsigned int>::min());
185 
186  assert(max_limit<long>() == std::numeric_limits<long>::max());
187  assert(min_limit<long>() == std::numeric_limits<long>::min());
188 
189  assert(max_limit<unsigned long>() == std::numeric_limits<unsigned long>::max());
190  assert(min_limit<unsigned long>() == std::numeric_limits<unsigned long>::min());
191 
192  assert(max_limit<float>() == std::numeric_limits<float>::max());
193  assert(min_limit<float>() == std::numeric_limits<float>::min());
194 
195  assert(max_limit<double>() == std::numeric_limits<double>::max());
196  assert(min_limit<double>() == std::numeric_limits<double>::min());
197 #endif
198 }
199 
200 void test5(void)
201 {
202  bool thrown;
204 
205  TEST(false,si = 0);
206  assert(si.value() == 0);
207  TEST(false,si++ == 0);
208  assert(si.value() == 1);
209  TEST(false,si++ == 1);
210  assert(si.value() == 2);
211  TEST(false,++si == 3);
212  assert(si.value() == 3);
213  TEST(false,si-- == 3);
214  assert(si.value() == 2);
215  TEST(false,--si == 1)
216  assert(si.value() == 1);
217  TEST(false,--si == 0);
218  TEST(true,--si == 0);
219  TEST(false,si = max_limit<unsigned short>());
220  TEST(true,++si == max_limit<unsigned short>());
221 
222  safe_num<unsigned short> si1, si2;
223 
224  si1 = 5;
225  si2 = 6;
226  assert(si1 != si2);
227  assert(si1 < si2);
228  assert(si2 > si1);
229  assert(si1 <= si2);
230  assert(si2 >= si1);
231  assert(si2 % si1 == 1);
232 
233  si = 10;
234  TEST(false,si += 5);
235  TEST(false,si == 15);
236  TEST(false,si -= 5);
237  TEST(false,si == 10);
238  TEST(false,si *= 5);
239  TEST(false,si == 50);
240  TEST(false,si /= 5);
241  TEST(false,si == 10);
242  TEST(false,si %= 6);
243  TEST(false,si == 4);
244 }
245 
246 void test6(void)
247 {
248  bool thrown;
249  safe_num<short> si;
250 
251  TEST(false,si = 0);
252  assert(si.value() == 0);
253  TEST(false,si++ == 0);
254  assert(si.value() == 1);
255  TEST(false,si++ == 1);
256  assert(si.value() == 2);
257  TEST(false,++si == 3);
258  assert(si.value() == 3);
259  TEST(false,si-- == 3);
260  assert(si.value() == 2);
261  TEST(false,--si == 1)
262  assert(si.value() == 1);
263  TEST(false,--si == 0);
264  TEST(false,--si == -1);
265  TEST(false,si = max_limit<short>());
266  TEST(true,++si == max_limit<short>());
267  TEST(false,si = min_limit<short>());
268  TEST(true,--si == max_limit<short>());
269 }
270 
271 void test7(void)
272 {
273  bool thrown;
274 
275  TEST(false,absolute(-max_limit<char>()));
276  TEST(true,absolute(min_limit<char>()));
277 }
278 
279 void test8(void)
280 {
281  short si;
282  safe_num<char> ci1, ci2, ci;
283  bool thrown;
284  bool should_throw;
285 
286  for (ci1 = min_limit<char>(); ci1 < max_limit<char>(); ++ci1)
287  {
288  for (ci2 = min_limit<char>(); ci2 < max_limit<char>(); ++ci2)
289  {
290  // addition
291  thrown = false;
292  try {
293  ci = ci1 + ci2;
294  }
295  catch(...) {
296  thrown = true;
297  }
298  should_throw = false;
299  si = ci1.value() + ci2.value();
300  if ((si > max_limit<char>()) || (si < min_limit<char>()))
301  should_throw = true;
302  if (ci2 == min_limit<char>())
303  should_throw = true;
304  assert(thrown == should_throw);
305 
306  // subtraction
307  thrown = false;
308  try {
309  ci = ci1 - ci2;
310  }
311  catch(...) {
312  thrown = true;
313  }
314  should_throw = false;
315  si = ci1.value() - ci2.value();
316  if ((si > max_limit<char>()) || (si < min_limit<char>()))
317  should_throw = true;
318  if (ci2 == min_limit<char>())
319  should_throw = true;
320  assert(thrown == should_throw);
321 
322  // multiplication
323  thrown = false;
324  try {
325  ci = ci1 * ci2;
326  }
327  catch(...) {
328  thrown = true;
329  }
330  should_throw = false;
331  si = ci1.value() * ci2.value();
332  if ((si > max_limit<char>()) || (si < min_limit<char>()))
333  should_throw = true;
334  if ((ci1 != 0) && (ci1 != 1) && (ci2 == min_limit<char>()))
335  should_throw = true;
336  assert(thrown == should_throw);
337 
338  // division
339  thrown = false;
340  try {
341  ci = ci1 / ci2;
342  }
343  catch(...) {
344  thrown = true;
345  }
346  should_throw = false;
347  if (ci2.value() == 0)
348  should_throw = true;
349  else {
350  si = ci1.value() / ci2.value();
351  if ((si > max_limit<char>()) || (si < min_limit<char>()))
352  should_throw = true;
353  }
354  assert(thrown == should_throw);
355 
356  }
357  }
358 }
359 
360 void test9(void)
361 {
362  uint64 free = 0;
363  uint64 total = 0;
364  safe_num<uint64> num = 0;
365 
366  free = 256258287ul;
367  total = 258030784ul;
368 
369  num = free;
370  num *= 100;
371  num /= total;
372 
373  free = 131067261ul;
374  total = 131072000ul;
375 
376  num = free;
377  num *= 100;
378  num /= total;
379 
380  free = 256258286ul;
381  total = 258030784ul;
382 
383  num = free;
384  num *= 100;
385  num /= total;
386 
387  free = 131067260ul;
388  total = 131072000ul;
389 
390  num = free;
391  num *= 100;
392  num /= total;
393 
394  free = 256258286ul;
395  total = 258030784ul;
396 
397  num = free;
398  num *= 100;
399  num /= total;
400 }
401 
402 int main(int argc, char const * argv[])
403 {
404  try {
405  test1();
406  test2();
407  test3();
408  test4();
409  test5();
410  test6();
411  test7();
412  test8();
413  test9();
414  }
415  catch(error e) {
416  std::cerr << e;
417  assert(0);
418  }
419  catch(...) {
420  std::cerr << err_unknown;
421  assert(0);
422  }
423  return(0);
424 }
425 
T absolute(const T &a_num)
Return the absolute value of a numeric type.
Definition: rmath.h:240
Safely manipulate numbers without worryiung about over/underflow error.
Definition: rmath.h:281
void test8(void)
Definition: test-rmath.cc:279
void test2(void)
Definition: test-rmath.cc:79
Basic types definitions and templates.
const T value(void) const
Return the value.
Definition: rmath.h:311
void test6(void)
Definition: test-rmath.cc:246
#define TEST(expected, code)
Definition: test-rmath.cc:18
static const T max_limit()
A small set of numeric limits routines, since gcc prior to 3.x doesn't have numeric_limits.
Definition: rmath.h:20
const float max_limit< float >()
Return the largest possible number that a float may hold.
Definition: rmath.h:86
void test7(void)
Definition: test-rmath.cc:271
#define err_unknown
Definition: error.h:114
An error class.
Definition: error.h:72
void test5(void)
Definition: test-rmath.cc:200
int main(int argc, char const *argv[])
Definition: test-rmath.cc:402
const double min_limit< double >()
Return the smallest positive number that a double may hold.
Definition: rmath.h:134
void test4(void)
Definition: test-rmath.cc:123
const float min_limit< float >()
Return the smallest positive number that a float may hold.
Definition: rmath.h:104
void test3(void)
Definition: test-rmath.cc:98
void test1(void)
Definition: test-rmath.cc:33
const double max_limit< double >()
Return the largest possible number that a double may hold.
Definition: rmath.h:116
void test9(void)
Definition: test-rmath.cc:360