summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--NEWS2
-rw-r--r--doc/gmp.texi2
-rw-r--r--gmpxx.h27
-rw-r--r--tests/cxx/t-ops2.cc9
5 files changed, 44 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index ac835594e..6c8626283 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,6 @@
2015-11-08 Marc Glisse <marc.glisse@inria.fr>
- * gmpxx.h (__gmp_fac_function): New class.
+ * gmpxx.h (__gmp_fac_function, __gmp_primorial_function): New classes.
(__GMPP_DECLARE_UNARY_STATIC_MEMFUN,
__GMPNN_DECLARE_UNARY_STATIC_MEMFUN,
__GMPNS_DECLARE_UNARY_STATIC_MEMFUN,
@@ -13,11 +13,12 @@
__GMPNU_DEFINE_UNARY_STATIC_MEMFUN,
__GMPND_DEFINE_UNARY_STATIC_MEMFUN, __GMPN_DEFINE_UNARY_STATIC_MEMFUN,
__GMP_DEFINE_UNARY_STATIC_MEMFUN): New macros.
- (factorial, mpz_class::factorial): New functions.
- * tests/cxx/t-ops2.cc: Test factorial.
+ (factorial, mpz_class::factorial, primorial, mpz_class::primorial):
+ New functions.
+ * tests/cxx/t-ops2.cc: Test factorial and primorial.
* tests/cxx/Makefile.am: Move t-ops2 after
t-do-exceptions-work-at-all-with-this-compiler.
- * doc/gmp.texi: Document factorial.
+ * doc/gmp.texi: Document factorial and primorial.
* NEWS: Likewise.
2015-11-07 Marc Glisse <marc.glisse@inria.fr>
diff --git a/NEWS b/NEWS
index 07b3ecc40..debf3bb48 100644
--- a/NEWS
+++ b/NEWS
@@ -7,7 +7,7 @@ medium, provided this notice is preserved.
Changes between GMP version 6.1.* and 6.2.0
FEATURES
- * New C++ function factorial for mpz_class.
+ * New C++ functions factorial and primorial for mpz_class.
Changes between GMP version 6.0.* and 6.1.0
diff --git a/doc/gmp.texi b/doc/gmp.texi
index d4a9c60fe..81246ef89 100644
--- a/doc/gmp.texi
+++ b/doc/gmp.texi
@@ -6865,6 +6865,8 @@ mpz_fdiv_q (q.get_mpz_t(), a.get_mpz_t(), d.get_mpz_t());
@deftypefunx mpz_class lcm (mpz_class @var{op1}, mpz_class @var{op2})
@deftypefunx mpz_class mpz_class::factorial (type @var{op})
@deftypefunx mpz_class factorial (mpz_class @var{op})
+@deftypefunx mpz_class mpz_class::primorial (type @var{op})
+@deftypefunx mpz_class primorial (mpz_class @var{op})
@maybepagebreak
@deftypefunx void mpz_class::swap (mpz_class& @var{op})
@deftypefunx void swap (mpz_class& @var{op1}, mpz_class& @var{op2})
diff --git a/gmpxx.h b/gmpxx.h
index 797865cae..fb0833491 100644
--- a/gmpxx.h
+++ b/gmpxx.h
@@ -1216,6 +1216,30 @@ struct __gmp_fac_function
{ __GMPXX_TMPZ_D; eval (z, temp); }
};
+struct __gmp_primorial_function
+{
+ static void eval(mpz_ptr z, unsigned long l) { mpz_primorial_ui(z, l); }
+ static void eval(mpz_ptr z, signed long l)
+ {
+ if (l < 0)
+ mpz_set_ui(z, 1);
+ else
+ eval(z, static_cast<unsigned long>(l));
+ }
+ static void eval(mpz_ptr z, mpz_srcptr w)
+ {
+ if (!mpz_fits_ulong_p(w))
+ if (mpz_sgn(w) < 0)
+ mpz_set_ui(z, 1);
+ else
+ throw std::bad_alloc(); // or std::overflow_error ("factorial")?
+ else
+ eval(z, mpz_get_ui(w));
+ }
+ static void eval(mpz_ptr z, double d)
+ { __GMPXX_TMPZ_D; eval (z, temp); }
+};
+
/**************** Auxiliary classes ****************/
@@ -1659,6 +1683,7 @@ public:
__GMP_DECLARE_INCREMENT_OPERATOR(operator--)
__GMP_DECLARE_UNARY_STATIC_MEMFUN(mpz_t, factorial, __gmp_fac_function)
+ __GMP_DECLARE_UNARY_STATIC_MEMFUN(mpz_t, primorial, __gmp_primorial_function)
};
typedef __gmp_expr<mpz_t, mpz_t> mpz_class;
@@ -3249,6 +3274,7 @@ __GMP_DEFINE_UNARY_FUNCTION_1(mpf_t, ceil, __gmp_ceil_function)
__GMP_DEFINE_UNARY_FUNCTION_1(mpf_t, sqrt, __gmp_sqrt_function)
__GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, sqrt, __gmp_sqrt_function)
__GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, factorial, __gmp_fac_function)
+__GMP_DEFINE_UNARY_FUNCTION_1(mpz_t, primorial, __gmp_primorial_function)
__GMP_DEFINE_BINARY_FUNCTION_1(mpf_t, hypot, __gmp_hypot_function)
__GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, gcd, __gmp_gcd_function)
__GMP_DEFINE_BINARY_FUNCTION_1(mpz_t, lcm, __gmp_lcm_function)
@@ -3279,6 +3305,7 @@ __GMPZ_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
__GMPZ_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
__GMP_DEFINE_UNARY_STATIC_MEMFUN(mpz_t, mpz_class::factorial, __gmp_fac_function)
+__GMP_DEFINE_UNARY_STATIC_MEMFUN(mpz_t, mpz_class::primorial, __gmp_primorial_function)
// member operators for mpq_class
diff --git a/tests/cxx/t-ops2.cc b/tests/cxx/t-ops2.cc
index ac8ea0d65..1403b4ab8 100644
--- a/tests/cxx/t-ops2.cc
+++ b/tests/cxx/t-ops2.cc
@@ -158,6 +158,15 @@ void checkz (){
catch (std::domain_error) {}
try { ret=factorial(mpz_class(1)<<300); ASSERT_ALWAYS(0); }
catch (std::bad_alloc) {}
+ ASSERT_ALWAYS(mpz_class::primorial(mpz_class(3))==6);
+ ASSERT_ALWAYS(mpz_class::primorial(mpz_class(2)*2)==6);
+ ASSERT_ALWAYS(mpz_class::primorial(3)==6);
+ ASSERT_ALWAYS(mpz_class::primorial(3ul)==6);
+ ASSERT_ALWAYS(mpz_class::primorial(3.f)==6);
+ ASSERT_ALWAYS(mpz_class::primorial(-mpz_class(3))==1);
+ ASSERT_ALWAYS(mpz_class::primorial(-5)==1);
+ try { ret=primorial(mpz_class(1)<<300); ASSERT_ALWAYS(0); }
+ catch (std::bad_alloc) {}
}
template<class T>