test_mixed_cpp_int.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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
  5. //
  6. // Compare arithmetic results using fixed_int to GMP results.
  7. //
  8. #ifdef _MSC_VER
  9. #define _SCL_SECURE_NO_WARNINGS
  10. #endif
  11. #include <boost/multiprecision/cpp_int.hpp>
  12. #include "test.hpp"
  13. template <class Number, class BigNumber>
  14. void test()
  15. {
  16. using namespace boost::multiprecision;
  17. typedef Number test_type;
  18. test_type h = (std::numeric_limits<test_type>::max)();
  19. test_type l = (std::numeric_limits<test_type>::max)();
  20. BigNumber r;
  21. add(r, h, h);
  22. BOOST_CHECK_EQUAL(r, cpp_int(h) + cpp_int(h));
  23. multiply(r, h, h);
  24. BOOST_CHECK_EQUAL(r, cpp_int(h) * cpp_int(h));
  25. if (std::numeric_limits<test_type>::is_signed)
  26. {
  27. subtract(r, l, h);
  28. BOOST_CHECK_EQUAL(r, cpp_int(l) - cpp_int(h));
  29. subtract(r, h, l);
  30. BOOST_CHECK_EQUAL(r, cpp_int(h) - cpp_int(l));
  31. multiply(r, l, l);
  32. BOOST_CHECK_EQUAL(r, cpp_int(l) * cpp_int(l));
  33. }
  34. //
  35. // Try again with integer types as the source:
  36. //
  37. enum
  38. {
  39. max_digits = std::numeric_limits<test_type>::is_signed ? std::numeric_limits<long long>::digits : std::numeric_limits<unsigned long long>::digits
  40. };
  41. enum
  42. {
  43. require_digits = std::numeric_limits<test_type>::digits <= 2 * max_digits ? std::numeric_limits<test_type>::digits / 2 : max_digits
  44. };
  45. typedef typename boost::uint_t<require_digits>::least uint_least;
  46. typedef typename boost::int_t<require_digits>::least int_least;
  47. typedef typename boost::mpl::if_c<std::numeric_limits<test_type>::is_signed, int_least, uint_least>::type i_type;
  48. i_type ih = (std::numeric_limits<i_type>::max)();
  49. i_type il = (std::numeric_limits<i_type>::max)();
  50. add(r, ih, ih);
  51. BOOST_CHECK_EQUAL(r, cpp_int(ih) + cpp_int(ih));
  52. multiply(r, ih, ih);
  53. BOOST_CHECK_EQUAL(r, cpp_int(ih) * cpp_int(ih));
  54. if (std::numeric_limits<test_type>::is_signed)
  55. {
  56. subtract(r, il, ih);
  57. BOOST_CHECK_EQUAL(r, cpp_int(il) - cpp_int(ih));
  58. subtract(r, ih, il);
  59. BOOST_CHECK_EQUAL(r, cpp_int(ih) - cpp_int(il));
  60. multiply(r, il, il);
  61. BOOST_CHECK_EQUAL(r, cpp_int(il) * cpp_int(il));
  62. }
  63. }
  64. void test_rational_mixed()
  65. {
  66. using namespace boost::multiprecision;
  67. cpp_int a(2);
  68. cpp_rational r(10);
  69. BOOST_CHECK_EQUAL(a + -r, -8);
  70. BOOST_CHECK_EQUAL(-r + a, -8);
  71. BOOST_CHECK_EQUAL(-a + r, 8);
  72. BOOST_CHECK_EQUAL(r + -a, 8);
  73. BOOST_CHECK_EQUAL(a - -r, 12);
  74. BOOST_CHECK_EQUAL(-r - a, -12);
  75. BOOST_CHECK_EQUAL(-a - r, -12);
  76. BOOST_CHECK_EQUAL(r - -a, 12);
  77. BOOST_CHECK_EQUAL(a * -r, -20);
  78. BOOST_CHECK_EQUAL(-r * a, -20);
  79. BOOST_CHECK_EQUAL(-a * r, -20);
  80. BOOST_CHECK_EQUAL(r * -a, -20);
  81. BOOST_CHECK_EQUAL(a / -r, cpp_rational(-2, 10));
  82. BOOST_CHECK_EQUAL(-r / a, -5);
  83. BOOST_CHECK_EQUAL(cpp_rational(-a / r), cpp_rational(-2, 10));
  84. BOOST_CHECK_EQUAL(r / -a, -5);
  85. }
  86. int main()
  87. {
  88. using namespace boost::multiprecision;
  89. test_rational_mixed();
  90. test<checked_int512_t, checked_int1024_t>();
  91. test<checked_int256_t, checked_int512_t>();
  92. test<number<cpp_int_backend<64, 64, signed_magnitude, checked, void>, et_off>, checked_int128_t>();
  93. test<boost::int64_t, checked_int128_t>();
  94. test<checked_uint512_t, checked_uint1024_t>();
  95. test<checked_uint256_t, checked_uint512_t>();
  96. test<number<cpp_int_backend<64, 64, unsigned_magnitude, checked, void>, et_off>, checked_uint128_t>();
  97. test<boost::uint64_t, checked_int128_t>();
  98. return boost::report_errors();
  99. }