• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // test performance.cpp : Defines the entry point for the console application.
2 //
3 
4 #include <cstdio>
5 #include <cstdint>
6 #include <iostream>
7 #include <chrono>
8 #include <boost/multiprecision/cpp_int.hpp>
9 #include <boost/multiprecision/integer.hpp>
10 
11 #include <boost/safe_numerics/safe_integer.hpp>
12 
13 typedef boost::safe_numerics::safe<unsigned> safe_type;
14 
15 namespace boost {
16 namespace multiprecision {
17 
18     template <class Integer, class I2>
19     typename enable_if_c<boost::safe_numerics::is_safe<Integer>::value, Integer&>::type
multiply(Integer & result,const I2 & a,const I2 & b)20     multiply(Integer& result, const I2& a, const I2& b){
21         return result = static_cast<Integer>(a) * static_cast<Integer>(b);
22     }
23 
24     template <class Integer>
25     typename enable_if_c<boost::safe_numerics::is_safe<Integer>::value, bool>::type
bit_test(const Integer & val,unsigned index)26     bit_test(const Integer& val, unsigned index){
27         Integer mask = 1;
28         if (index >= sizeof(Integer) * CHAR_BIT)
29             return 0;
30         if (index)
31             mask <<= index;
32         return val & mask ? true : false;
33     }
34 
35     template <class I1, class I2>
36     typename enable_if_c<boost::safe_numerics::is_safe<I1>::value, I2>::type
integer_modulus(const I1 & x,I2 val)37     integer_modulus(const I1& x, I2 val){
38         return x % val;
39     }
40 
41     namespace detail {
42         template <class T> struct double_integer;
43 
44         template <>
45         struct double_integer<safe_type>{
46             using type = boost::safe_numerics::safe<std::uint64_t>;
47         };
48     }
49 
50     template <class I1, class I2, class I3>
51     typename enable_if_c<boost::safe_numerics::is_safe<I1>::value, I1>::type
powm(const I1 & a,I2 b,I3 c)52     powm(const I1& a, I2 b, I3 c){
53         typedef typename detail::double_integer<I1>::type double_type;
54 
55         I1 x(1), y(a);
56         double_type result;
57 
58         while (b > 0){
59             if (b & 1){
60                 multiply(result, x, y);
61                 x = integer_modulus(result, c);
62             }
63             multiply(result, y, y);
64             y = integer_modulus(result, c);
65             b >>= 1;
66         }
67         return x % c;
68     }
69 
70     template <class T, class PP, class EP>
71     inline unsigned
lsb(const boost::safe_numerics::safe<T,PP,EP> & x)72     lsb(const boost::safe_numerics::safe<T, PP, EP>& x){
73         return lsb(static_cast<T>(x));
74     }
75 
76 } }
77 
78 #include <boost/multiprecision/miller_rabin.hpp>
79 
80 template <class Clock>
81 class stopwatch
82 {
83     const typename Clock::time_point m_start;
84 public:
stopwatch()85     stopwatch() :
86         m_start(Clock::now())
87     {}
elapsed() const88     typename Clock::duration elapsed() const {
89         return Clock::now() - m_start;
90     }
91 };
92 
93 template<typename T>
test(const char * msg)94 void test(const char * msg){
95     const stopwatch<std::chrono::high_resolution_clock> c;
96 
97     unsigned count = 0;
98     for (T i = 3; i < 30000000; ++i)
99         if (boost::multiprecision::miller_rabin_test(i, 25)) ++count;
100 
101     std::chrono::duration<double> time = c.elapsed();
102     std::cout<< msg << ":\ntime = " << time.count();
103     std::cout << "\ncount = " << count << std::endl;
104 }
105 
main()106 int main()
107 {
108     test<unsigned>("Testing type unsigned");
109     test<boost::safe_numerics::safe<unsigned>>("Testing type safe<unsigned>");
110     return 0;
111 }
112 
113