]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/multiprecision/test/test_checked_cpp_int.cpp
1 ///////////////////////////////////////////////////////////////
2 // Copyright 2012 John Maddock. Distributed under the Boost
3 // Software License, Version 1.0. (See accompanying file
4 // LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
7 // Compare arithmetic results using fixed_int to GMP results.
11 #define _SCL_SECURE_NO_WARNINGS
14 #include <boost/multiprecision/cpp_int.hpp>
16 #include <boost/random/mersenne_twister.hpp>
17 #include <boost/random/uniform_int.hpp>
20 T
generate_random(unsigned bits_wanted
)
22 static boost::random::mt19937 gen
;
23 typedef boost::random::mt19937::result_type random_type
;
27 if (std::numeric_limits
<T
>::is_bounded
&& (bits_wanted
== (unsigned)std::numeric_limits
<T
>::digits
))
29 max_val
= (std::numeric_limits
<T
>::max
)();
30 digits
= std::numeric_limits
<T
>::digits
;
34 max_val
= T(1) << bits_wanted
;
38 unsigned bits_per_r_val
= std::numeric_limits
<random_type
>::digits
- 1;
39 while ((random_type(1) << bits_per_r_val
) > (gen
.max
)())
42 unsigned terms_needed
= digits
/ bits_per_r_val
+ 1;
45 for (unsigned i
= 0; i
< terms_needed
; ++i
)
54 template <class Number
>
55 void test_signed_overflow(Number a
, Number b
, const std::integral_constant
<bool, true>&)
58 BOOST_CHECK_THROW(Number(a
* b
), std::overflow_error
);
60 BOOST_CHECK(Number(a
* b
) >= (std::numeric_limits
<Number
>::min
)());
62 template <class Number
>
63 void test_signed_overflow(Number
, Number
, const std::integral_constant
<bool, false>&)
67 template <class Number
>
70 using namespace boost::multiprecision
;
71 typedef Number test_type
;
73 if (std::numeric_limits
<test_type
>::is_bounded
)
75 test_type val
= (std::numeric_limits
<test_type
>::max
)();
76 #ifndef BOOST_NO_EXCEPTIONS
77 BOOST_CHECK_THROW(++val
, std::overflow_error
);
78 val
= (std::numeric_limits
<test_type
>::max
)();
79 BOOST_CHECK_THROW(test_type(1 + val
), std::overflow_error
);
80 BOOST_CHECK_THROW(test_type(val
+ 1), std::overflow_error
);
81 BOOST_CHECK_THROW(test_type(2 * val
), std::overflow_error
);
84 BOOST_CHECK_THROW(test_type(2 * val
), std::overflow_error
);
86 if (std::numeric_limits
<test_type
>::is_signed
)
88 val
= (std::numeric_limits
<test_type
>::min
)();
89 BOOST_CHECK_THROW(--val
, std::overflow_error
);
90 val
= (std::numeric_limits
<test_type
>::min
)();
91 BOOST_CHECK_THROW(test_type(val
- 1), std::overflow_error
);
92 BOOST_CHECK_THROW(test_type(2 * val
), std::overflow_error
);
95 BOOST_CHECK_THROW(test_type(2 * val
), std::overflow_error
);
99 val
= (std::numeric_limits
<test_type
>::min
)();
100 BOOST_CHECK_THROW(--val
, std::range_error
);
101 val
= (std::numeric_limits
<test_type
>::min
)();
102 BOOST_CHECK_THROW(test_type(val
- 1), std::range_error
);
106 // Test overflow in random values:
108 for (unsigned bits
= 30; bits
< std::numeric_limits
<test_type
>::digits
; bits
+= 30)
110 for (unsigned i
= 0; i
< 100; ++i
)
112 val
= static_cast<test_type
>(generate_random
<cpp_int
>(bits
));
113 test_type val2
= 1 + (std::numeric_limits
<test_type
>::max
)() / val
;
114 BOOST_CHECK_THROW(test_type(val2
* val
), std::overflow_error
);
115 test_signed_overflow(val2
, val
, std::integral_constant
<bool, std::numeric_limits
<test_type
>::is_signed
>());
117 BOOST_CHECK(cpp_int(val2
) * cpp_int(val
) <= cpp_int((std::numeric_limits
<test_type
>::max
)()));
118 BOOST_CHECK(val2
* val
<= (std::numeric_limits
<test_type
>::max
)());
119 val2
= (std::numeric_limits
<test_type
>::max
)() - val
;
121 BOOST_CHECK_THROW(test_type(val2
+ val
), std::overflow_error
);
122 BOOST_CHECK((val2
- 1) + val
== (std::numeric_limits
<test_type
>::max
)());
123 if (std::numeric_limits
<test_type
>::is_signed
)
125 val2
= (std::numeric_limits
<test_type
>::min
)() + val
;
127 BOOST_CHECK_THROW(test_type(val2
- val
), std::overflow_error
);
129 BOOST_CHECK(val2
- val
== (std::numeric_limits
<test_type
>::min
)());
131 unsigned shift
= std::numeric_limits
<test_type
>::digits
- msb(val
);
132 BOOST_CHECK_THROW((val
<< shift
) > 0, std::overflow_error
);
137 #ifndef BOOST_NO_EXCEPTIONS
138 if (std::numeric_limits
<test_type
>::is_signed
)
142 BOOST_CHECK_THROW(test_type(a
| b
), std::range_error
);
143 BOOST_CHECK_THROW(test_type(a
& b
), std::range_error
);
144 BOOST_CHECK_THROW(test_type(a
^ b
), std::range_error
);
148 // Constructing from a negative value is not allowed:
149 BOOST_CHECK_THROW(test_type(-2), std::range_error
);
150 BOOST_CHECK_THROW(test_type("-2"), std::range_error
);
152 if (std::numeric_limits
<test_type
>::digits
< std::numeric_limits
<long long>::digits
)
154 long long llm
= (std::numeric_limits
<long long>::max
)();
156 BOOST_CHECK_THROW(t
= llm
, std::range_error
);
157 BOOST_CHECK_THROW(t
= static_cast<test_type
>(llm
), std::range_error
);
158 unsigned long long ullm
= (std::numeric_limits
<unsigned long long>::max
)();
159 BOOST_CHECK_THROW(t
= ullm
, std::range_error
);
160 BOOST_CHECK_THROW(t
= static_cast<test_type
>(ullm
), std::range_error
);
162 static const checked_uint512_t big
= (std::numeric_limits
<checked_uint512_t
>::max
)();
163 BOOST_CHECK_THROW(t
= static_cast<test_type
>(big
), std::range_error
);
168 BOOST_CHECK_THROW(test_type("12A"), std::runtime_error
);
169 BOOST_CHECK_THROW(test_type("0658"), std::runtime_error
);
171 if (std::numeric_limits
<test_type
>::is_signed
)
173 BOOST_CHECK_THROW(test_type(-2).str(0, std::ios_base::hex
), std::runtime_error
);
174 BOOST_CHECK_THROW(test_type(-2).str(0, std::ios_base::oct
), std::runtime_error
);
181 using namespace boost::multiprecision
;
183 test
<number
<cpp_int_backend
<0, 0, signed_magnitude
, checked
> > >();
184 test
<checked_int512_t
>();
185 test
<checked_uint512_t
>();
186 test
<number
<cpp_int_backend
<32, 32, signed_magnitude
, checked
, void> > >();
187 test
<number
<cpp_int_backend
<32, 32, unsigned_magnitude
, checked
, void> > >();
190 // We also need to test type with "odd" bit counts in order to ensure full code coverage:
192 test
<number
<cpp_int_backend
<528, 528, signed_magnitude
, checked
, void> > >();
193 test
<number
<cpp_int_backend
<528, 528, unsigned_magnitude
, checked
, void> > >();
194 test
<number
<cpp_int_backend
<48, 48, signed_magnitude
, checked
, void> > >();
195 test
<number
<cpp_int_backend
<48, 48, unsigned_magnitude
, checked
, void> > >();
196 return boost::report_errors();