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

mercurial at gmplib.org mercurial at gmplib.org
Thu Nov 12 06:00:08 UTC 2015


details:   /var/hg/gmp/rev/f6cd9c29e66c
changeset: 16958:f6cd9c29e66c
user:      Marc Glisse <marc.glisse at inria.fr>
date:      Thu Nov 12 07:00:04 2015 +0100
description:
New C++ function fibonacci.

diffstat:

 ChangeLog            |   8 ++++++++
 doc/gmp.texi         |   2 ++
 gmpxx.h              |  47 +++++++++++++++++++++++++++++++++++++++--------
 tests/cxx/t-ops2z.cc |   9 +++++++++
 4 files changed, 58 insertions(+), 8 deletions(-)

diffs (137 lines):

diff -r 7db76d280783 -r f6cd9c29e66c ChangeLog
--- a/ChangeLog	Tue Nov 10 22:20:39 2015 +0100
+++ b/ChangeLog	Thu Nov 12 07:00:04 2015 +0100
@@ -1,3 +1,11 @@
+2015-11-12  Marc Glisse  <marc.glisse at inria.fr>
+
+	* gmpxx.h (__gmp_fibonacci_function): New class.
+	(fibonacci, mpz_class::fibonacci): New functions.
+	(__gmp_fac_function, __gmp_primorial_function): Add braces.
+	* tests/cxx/t-ops2z.cc: Test fibonacci.
+	* doc/gmp.texi: Document fibonacci.
+
 2015-11-10  Marc Glisse  <marc.glisse at inria.fr>
 
 	* gmpxx.h (__gmp_primorial_function): Throw on negative operands.
diff -r 7db76d280783 -r f6cd9c29e66c doc/gmp.texi
--- a/doc/gmp.texi	Tue Nov 10 22:20:39 2015 +0100
+++ b/doc/gmp.texi	Thu Nov 12 07:00:04 2015 +0100
@@ -6867,6 +6867,8 @@
 @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})
+ at deftypefunx mpz_class mpz_class::fibonacci (type @var{op})
+ at deftypefunx mpz_class fibonacci (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 7db76d280783 -r f6cd9c29e66c gmpxx.h
--- a/gmpxx.h	Tue Nov 10 22:20:39 2015 +0100
+++ b/gmpxx.h	Thu Nov 12 07:00:04 2015 +0100
@@ -1206,10 +1206,12 @@
   static void eval(mpz_ptr z, mpz_srcptr w)
   {
     if (!mpz_fits_ulong_p(w))
-      if (mpz_sgn(w) < 0)
-	throw std::domain_error ("factorial(negative)");
-      else
-	throw std::bad_alloc(); // or std::overflow_error ("factorial")?
+      {
+	if (mpz_sgn(w) < 0)
+	  throw std::domain_error ("factorial(negative)");
+	else
+	  throw std::bad_alloc(); // or std::overflow_error ("factorial")?
+      }
     eval(z, mpz_get_ui(w));
   }
   static void eval(mpz_ptr z, double d)
@@ -1228,16 +1230,42 @@
   static void eval(mpz_ptr z, mpz_srcptr w)
   {
     if (!mpz_fits_ulong_p(w))
-      if (mpz_sgn(w) < 0)
-	throw std::domain_error ("primorial(negative)");
-      else
-	throw std::bad_alloc(); // or std::overflow_error ("primorial")?
+      {
+	if (mpz_sgn(w) < 0)
+	  throw std::domain_error ("primorial(negative)");
+	else
+	  throw std::bad_alloc(); // or std::overflow_error ("primorial")?
+      }
     eval(z, mpz_get_ui(w));
   }
   static void eval(mpz_ptr z, double d)
   {  __GMPXX_TMPZ_D;    eval (z, temp); }
 };
 
+struct __gmp_fib_function
+{
+  static void eval(mpz_ptr z, unsigned long l) { mpz_fib_ui(z, l); }
+  static void eval(mpz_ptr z, signed long l)
+  {
+    if (l < 0)
+      {
+	eval(z, -static_cast<unsigned long>(l));
+	if ((l & 1) == 0)
+	  mpz_neg(z, z);
+      }
+    else
+      eval(z, static_cast<unsigned long>(l));
+  }
+  static void eval(mpz_ptr z, mpz_srcptr w)
+  {
+    if (!mpz_fits_slong_p(w))
+      throw std::bad_alloc(); // or std::overflow_error ("fibonacci")?
+    eval(z, mpz_get_si(w));
+  }
+  static void eval(mpz_ptr z, double d)
+  {  __GMPXX_TMPZ_D;    eval (z, temp); }
+};
+
 
 /**************** Auxiliary classes ****************/
 
@@ -1682,6 +1710,7 @@
 
   __GMP_DECLARE_UNARY_STATIC_MEMFUN(mpz_t, factorial, __gmp_fac_function)
   __GMP_DECLARE_UNARY_STATIC_MEMFUN(mpz_t, primorial, __gmp_primorial_function)
+  __GMP_DECLARE_UNARY_STATIC_MEMFUN(mpz_t, fibonacci, __gmp_fib_function)
 };
 
 typedef __gmp_expr<mpz_t, mpz_t> mpz_class;
@@ -3273,6 +3302,7 @@
 __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_UNARY_FUNCTION_1(mpz_t, fibonacci, __gmp_fib_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)
@@ -3304,6 +3334,7 @@
 
 __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)
+__GMP_DEFINE_UNARY_STATIC_MEMFUN(mpz_t, mpz_class::fibonacci, __gmp_fib_function)
 
 // member operators for mpq_class
 
diff -r 7db76d280783 -r f6cd9c29e66c tests/cxx/t-ops2z.cc
--- a/tests/cxx/t-ops2z.cc	Tue Nov 10 22:20:39 2015 +0100
+++ b/tests/cxx/t-ops2z.cc	Thu Nov 12 07:00:04 2015 +0100
@@ -105,6 +105,15 @@
   catch (std::domain_error) {}
   try { ret=primorial(mpz_class(1)<<300); ASSERT_ALWAYS(0); }
   catch (std::bad_alloc) {}
+  ASSERT_ALWAYS(mpz_class::fibonacci(mpz_class(6))==8);
+  ASSERT_ALWAYS(mpz_class::fibonacci(mpz_class(2)*2)==3);
+  ASSERT_ALWAYS(mpz_class::fibonacci(3)==2);
+  ASSERT_ALWAYS(mpz_class::fibonacci(3ul)==2);
+  ASSERT_ALWAYS(mpz_class::fibonacci(3.f)==2);
+  ASSERT_ALWAYS(fibonacci(-mpz_class(6))==-8);
+  ASSERT_ALWAYS(mpz_class::fibonacci(-3)==2);
+  try { ret=fibonacci(mpz_class(1)<<300); ASSERT_ALWAYS(0); }
+  catch (std::bad_alloc) {}
 }
 
 int


More information about the gmp-commit mailing list