[Gmp-commit] /var/hg/gmp: New C++ function primorial.

mercurial at gmplib.org mercurial at gmplib.org
Sun Nov 8 12:11:41 UTC 2015


details:   /var/hg/gmp/rev/a942ab0163d6
changeset: 16948:a942ab0163d6
user:      Marc Glisse <marc.glisse at inria.fr>
date:      Sun Nov 08 13:11:38 2015 +0100
description:
New C++ function primorial.

diffstat:

 ChangeLog           |   9 +++++----
 NEWS                |   2 +-
 doc/gmp.texi        |   2 ++
 gmpxx.h             |  27 +++++++++++++++++++++++++++
 tests/cxx/t-ops2.cc |   9 +++++++++
 5 files changed, 44 insertions(+), 5 deletions(-)

diffs (128 lines):

diff -r 4c011521fddd -r a942ab0163d6 ChangeLog
--- a/ChangeLog	Sun Nov 08 10:51:00 2015 +0100
+++ b/ChangeLog	Sun Nov 08 13:11:38 2015 +0100
@@ -1,6 +1,6 @@
 2015-11-08  Marc Glisse  <marc.glisse at 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 at inria.fr>
diff -r 4c011521fddd -r a942ab0163d6 NEWS
--- a/NEWS	Sun Nov 08 10:51:00 2015 +0100
+++ b/NEWS	Sun Nov 08 13:11:38 2015 +0100
@@ -7,7 +7,7 @@
 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 -r 4c011521fddd -r a942ab0163d6 doc/gmp.texi
--- a/doc/gmp.texi	Sun Nov 08 10:51:00 2015 +0100
+++ b/doc/gmp.texi	Sun Nov 08 13:11:38 2015 +0100
@@ -6865,6 +6865,8 @@
 @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})
+ at deftypefunx mpz_class mpz_class::primorial (type @var{op})
+ at 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 -r 4c011521fddd -r a942ab0163d6 gmpxx.h
--- a/gmpxx.h	Sun Nov 08 10:51:00 2015 +0100
+++ b/gmpxx.h	Sun Nov 08 13:11:38 2015 +0100
@@ -1216,6 +1216,30 @@
   {  __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 @@
   __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, 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_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 -r 4c011521fddd -r a942ab0163d6 tests/cxx/t-ops2.cc
--- a/tests/cxx/t-ops2.cc	Sun Nov 08 10:51:00 2015 +0100
+++ b/tests/cxx/t-ops2.cc	Sun Nov 08 13:11:38 2015 +0100
@@ -158,6 +158,15 @@
   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>


More information about the gmp-commit mailing list