Files
multiprecision/test/test_int_io.cpp
John Maddock 8433c69175 Disable expression templates for fixed precision types.
Restrict integer functions to integer types.
Improve Miller Rabin performance by filtering out small primes etc.
Improve Miller Rabin tests.
Change mp_int to tom_int to avoid conflict with global ::mp_Int type.

[SVN r77471]
2012-03-22 10:29:30 +00:00

133 lines
3.9 KiB
C++

// Copyright John Maddock 2011.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifdef _MSC_VER
# define _SCL_SECURE_NO_WARNINGS
#endif
#if !defined(TEST_MPZ) && !defined(TEST_TOMMATH) && !defined(TEST_CPP_INT)
# define TEST_TOMMATH
# define TEST_MPZ
# define TEST_CPP_INT
#ifdef _MSC_VER
#pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!")
#endif
#ifdef __GNUC__
#pragma warning "CAUTION!!: No backend type specified so testing everything.... this will take some time!!"
#endif
#endif
#if defined(TEST_MPZ)
#include <boost/multiprecision/gmp.hpp>
#endif
#if defined(TEST_TOMMATH)
#include <boost/multiprecision/tommath.hpp>
#endif
#ifdef TEST_CPP_INT
#include <boost/multiprecision/cpp_int.hpp>
#endif
#include <boost/algorithm/string/case_conv.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int.hpp>
#include "test.hpp"
#include <iostream>
#include <iomanip>
template <class T>
T generate_random()
{
static boost::random::uniform_int_distribution<unsigned> ui(0, 20);
static boost::random::mt19937 gen;
T val = gen();
unsigned lim = ui(gen);
for(unsigned i = 0; i < lim; ++i)
{
val *= (gen.max)();
val += gen();
}
return val;
}
template <class T>
void do_round_trip(const T& val, std::ios_base::fmtflags f)
{
std::stringstream ss;
#ifndef BOOST_NO_NUMERIC_LIMITS_LOWEST
ss << std::setprecision(std::numeric_limits<T>::max_digits10);
#else
ss << std::setprecision(std::numeric_limits<T>::digits10 + 5);
#endif
ss.flags(f);
ss << val;
T new_val = ss.str();
BOOST_CHECK_EQUAL(new_val, val);
new_val = val.str(0, f);
BOOST_CHECK_EQUAL(new_val, val);
}
template <class T>
void do_round_trip(const T& val)
{
do_round_trip(val, std::ios_base::fmtflags(0));
if(val >= 0)
{
do_round_trip(val, std::ios_base::fmtflags(std::ios_base::showbase|std::ios_base::hex));
do_round_trip(val, std::ios_base::fmtflags(std::ios_base::showbase|std::ios_base::oct));
}
}
template <class T>
void test_round_trip()
{
for(unsigned i = 0; i < 1000; ++i)
{
T val = generate_random<T>();
do_round_trip(val);
if(std::numeric_limits<T>::is_signed)
do_round_trip(T(-val));
}
BOOST_CHECK_EQUAL(T(1002).str(), "1002");
BOOST_CHECK_EQUAL(T(1002).str(0, std::ios_base::showpos), "+1002");
if(std::numeric_limits<T>::is_signed)
{
BOOST_CHECK_EQUAL(T(-1002).str(), "-1002");
}
BOOST_CHECK_EQUAL(T(1002).str(0, std::ios_base::oct), "1752");
BOOST_CHECK_EQUAL(T(1002).str(0, std::ios_base::oct|std::ios_base::showbase), "01752");
BOOST_CHECK_EQUAL(boost::to_lower_copy(T(1002).str(0, std::ios_base::hex)), "3ea");
BOOST_CHECK_EQUAL(boost::to_lower_copy(T(1002).str(0, std::ios_base::hex|std::ios_base::showbase)), "0x3ea");
BOOST_CHECK_EQUAL(T(1002).str(0, std::ios_base::dec), "1002");
BOOST_CHECK_EQUAL(T(1002).str(0, std::ios_base::dec|std::ios_base::showbase), "1002");
if(std::numeric_limits<T>::is_signed && !std::numeric_limits<T>::is_modulo)
{
BOOST_CHECK_THROW(T(-2).str(0, std::ios_base::oct), std::runtime_error);
BOOST_CHECK_THROW(T(-2).str(0, std::ios_base::hex), std::runtime_error);
}
}
int main()
{
#ifdef TEST_MPZ
test_round_trip<boost::multiprecision::mpz_int>();
#endif
#ifdef TEST_TOMMATH
test_round_trip<boost::multiprecision::tom_int>();
#endif
#ifdef TEST_CPP_INT
test_round_trip<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<> > >();
test_round_trip<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<1024, true, void> > >();
test_round_trip<boost::multiprecision::mp_number<boost::multiprecision::cpp_int_backend<512, false, void> > >();
#endif
return boost::report_errors();
}