1 ///
2 /// @file  fast_div.cpp
3 /// @brief Test fast_div(x, y) function
4 ///
5 /// Copyright (C) 2020 Kim Walisch, <kim.walisch@gmail.com>
6 ///
7 /// This file is distributed under the BSD License. See the COPYING
8 /// file in the top level directory.
9 ///
10 
11 #include <fast_div.hpp>
12 #include <int128_t.hpp>
13 
14 #include <stdint.h>
15 #include <cstdlib>
16 #include <iostream>
17 #include <limits>
18 #include <random>
19 #include <type_traits>
20 
21 using namespace primecount;
22 
23 static_assert(std::is_same<make_smaller<int32_t>::type, uint32_t>::value,
24               "make_smaller<int32_t>::type != uint32_t");
25 
26 #if defined(ENABLE_DIV32)
27 
28 static_assert(std::is_same<make_smaller<uint64_t>::type, uint32_t>::value,
29               "make_smaller<uint64_t>::type != uint32_t");
30 
31 #else
32 
33 static_assert(std::is_same<make_smaller<uint64_t>::type, uint64_t>::value,
34               "make_smaller<uint64_t>::type != uint64_t");
35 
36 #endif
37 
38 #ifdef HAVE_INT128_T
39 
40 static_assert(std::is_same<make_smaller<int128_t>::type, uint64_t>::value,
41               "make_smaller<int128_t>::type != uint64_t");
42 
43 #endif
44 
check(bool OK)45 void check(bool OK)
46 {
47   std::cout << "   " << (OK ? "OK" : "ERROR") << "\n";
48   if (!OK)
49     std::exit(1);
50 }
51 
main()52 int main()
53 {
54   std::random_device rd;
55   std::mt19937 gen(rd());
56 
57   std::uniform_int_distribution<int32_t> dist_i32(1, std::numeric_limits<int32_t>::max());
58   std::uniform_int_distribution<uint64_t> dist_u64(0, std::numeric_limits<uint64_t>::max());
59 
60   for (int i = 0; i < 10000; i++)
61   {
62     uint64_t x = dist_i32(gen);
63      int32_t y = dist_i32(gen);
64     uint64_t res = fast_div(x, y);
65 
66     std::cout << "fast_div(" << x << ", " << y << ") = " << res;
67     check(res == x / y);
68 
69     x = dist_u64(gen);
70     y = dist_i32(gen);
71     res = fast_div(x, y);
72 
73     std::cout << "fast_div(" << x << ", " << y << ") = " << res;
74     check(res == x / y);
75   }
76 
77 #ifdef HAVE_INT128_T
78 
79   std::uniform_int_distribution<int128_t> dist_i128(0, std::numeric_limits<int128_t>::max());
80 
81   for (int i = 0; i < 10000; i++)
82   {
83     int128_t x = dist_u64(gen);
84      int32_t y = dist_i32(gen);
85     int128_t res = fast_div(x, y);
86 
87     std::cout << "fast_div(" << x << ", " << y << ") = " << res;
88     check(res == x / y);
89 
90     x = dist_i128(gen);
91     y = dist_i32(gen);
92     res = fast_div(x, y);
93 
94     std::cout << "fast_div(" << x << ", " << y << ") = " << res;
95     check(res == x / y);
96   }
97 
98 #endif
99 
100   std::cout << std::endl;
101   std::cout << "All tests passed successfully!" << std::endl;
102 
103   return 0;
104 }
105