Skip to content

Commit 5375a1d

Browse files
committed
Added additional tests, benchmarks, and overflow checks
1 parent d762398 commit 5375a1d

File tree

3 files changed

+44
-4
lines changed

3 files changed

+44
-4
lines changed

include/boost/math/special_functions/prime_functions.hpp renamed to include/boost/math/special_functions/prime_sieve.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <deque>
1414
#include <vector>
1515
#include <iterator>
16+
#include <iostream>
1617

1718
namespace boost { namespace math
1819
{
@@ -23,6 +24,7 @@ template<class Z, class OutputIterator>
2324
auto prime_sieve(Z lower_bound, Z upper_bound, OutputIterator output) -> decltype(output)
2425
{
2526
static_assert(std::is_integral<Z>::value, "No primes for floating point types");
27+
BOOST_ASSERT_MSG(upper_bound + 1 < std::numeric_limits<Z>::max(), "Type Overflow");
2628
std::vector<Z> least_divisors(upper_bound + 1, 0);
2729
std::deque<Z> primes;
2830

reporting/performance/prime_functions_performance.cpp renamed to reporting/performance/prime_sieve_performance.cpp

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
// (See accompanying file LICENSE_1_0.txt
66
// or copy at http://www.boost.org/LICENSE_1_0.txt)
77

8-
#include "../../include/boost/math/special_functions/prime_functions.hpp"
9-
8+
#include <boost/math/special_functions/prime_sieve.hpp>
109
#include <benchmark/benchmark.h>
1110

1211
template <class Z>
@@ -18,6 +17,19 @@ void prime_sieve(benchmark::State& state)
1817
std::vector<Z> primes;
1918
benchmark::DoNotOptimize(boost::math::prime_sieve(static_cast<Z>(2), upper, std::back_inserter(primes)));
2019
}
20+
state.SetComplexityN(state.range(0));
21+
}
22+
23+
template <typename Z>
24+
void prime_range(benchmark::State& state)
25+
{
26+
Z upper = static_cast<Z>(state.range(0));
27+
for(auto _ : state)
28+
{
29+
std::vector<Z> primes;
30+
benchmark::DoNotOptimize(boost::math::prime_range(static_cast<Z>(2), upper, std::back_inserter(primes)));
31+
}
32+
state.SetComplexityN(state.range(0));
2133
}
2234

2335
template <class Z>
@@ -30,6 +42,7 @@ void prime_sieve_partial_range(benchmark::State& state)
3042
std::vector<Z> primes;
3143
benchmark::DoNotOptimize(boost::math::prime_sieve(lower, upper, std::back_inserter(primes)));
3244
}
45+
state.SetComplexityN(state.range(0));
3346
}
3447

3548
BENCHMARK_TEMPLATE(prime_sieve, int32_t)->RangeMultiplier(2)->Range(1 << 1, 1 << 22)->Complexity();
@@ -38,5 +51,16 @@ BENCHMARK_TEMPLATE(prime_sieve, uint32_t)->RangeMultiplier(2)->Range(1 << 1, 1 <
3851
BENCHMARK_TEMPLATE(prime_sieve_partial_range, int32_t)->RangeMultiplier(2)->Range(1 << 1, 1 << 22)->Complexity();
3952
BENCHMARK_TEMPLATE(prime_sieve_partial_range, int64_t)->RangeMultiplier(2)->Range(1 << 1, 1 << 22)->Complexity();
4053
BENCHMARK_TEMPLATE(prime_sieve_partial_range, uint32_t)->RangeMultiplier(2)->Range(1 << 1, 1 << 22)->Complexity();
54+
BENCHMARK_TEMPLATE(prime_range, int32_t)->RangeMultiplier(2)->Range(1 << 1, 1 << 22)->Complexity();
55+
BENCHMARK_TEMPLATE(prime_range, int64_t)->RangeMultiplier(2)->Range(1 << 1, 1 << 22)->Complexity();
56+
BENCHMARK_TEMPLATE(prime_range, uint32_t)->RangeMultiplier(2)->Range(1 << 1, 1 << 22)->Complexity();
57+
58+
// Direct comparison of lookup vs sieve using only range of lookup
59+
BENCHMARK_TEMPLATE(prime_sieve, int32_t)->RangeMultiplier(2)->Range(1 << 1, 1 << 16)->Complexity();
60+
BENCHMARK_TEMPLATE(prime_range, int32_t)->RangeMultiplier(2)->Range(1 << 1, 1 << 16)->Complexity();
61+
BENCHMARK_TEMPLATE(prime_sieve, int64_t)->RangeMultiplier(2)->Range(1 << 1, 1 << 16)->Complexity();
62+
BENCHMARK_TEMPLATE(prime_range, int64_t)->RangeMultiplier(2)->Range(1 << 1, 1 << 16)->Complexity();
63+
BENCHMARK_TEMPLATE(prime_sieve, uint32_t)->RangeMultiplier(2)->Range(1 << 1, 1 << 16)->Complexity();
64+
BENCHMARK_TEMPLATE(prime_range, uint32_t)->RangeMultiplier(2)->Range(1 << 1, 1 << 16)->Complexity();
4165

4266
BENCHMARK_MAIN();

test/test_prime_functions.cpp renamed to test/test_prime_sieve.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
// (See accompanying file LICENSE_1_0.txt
66
// or copy at http://www.boost.org/LICENSE_1_0.txt)
77

8-
#include "../include/boost/math/special_functions/prime_functions.hpp"
9-
8+
#include <boost/math/special_functions/prime_sieve.hpp>
109
#include <boost/core/lightweight_test.hpp>
10+
#include <boost/multiprecision/cpp_int.hpp>
1111
#include <list>
1212
#include <deque>
1313
#include <array>
@@ -97,6 +97,16 @@ void test_prime_range()
9797
BOOST_TEST_EQ(primes.size(), ref);
9898
}
9999

100+
template<typename Z>
101+
void test_prime_sieve_overflow()
102+
{
103+
std::vector<Z> primes;
104+
105+
// Should die with call to BOOST_ASSERT
106+
boost::math::prime_sieve(static_cast<Z>(2), static_cast<Z>(std::numeric_limits<Z>::max()),
107+
std::back_inserter(primes));
108+
}
109+
100110
int main()
101111
{
102112
test_prime_sieve<int>();
@@ -109,5 +119,9 @@ int main()
109119
test_prime_range<int64_t>();
110120
test_prime_range<uint32_t>();
111121

122+
test_prime_sieve<boost::multiprecision::cpp_int>();
123+
124+
//test_prime_sieve_overflow<int16_t>();
125+
112126
boost::report_errors();
113127
}

0 commit comments

Comments
 (0)