]> www.ginac.de Git - ginac.git/blobdiff - ginac/numeric.cpp
[BUGFIX] Fix crash in parser.
[ginac.git] / ginac / numeric.cpp
index 1f87f422b05ccf9371119a0345083b9338084001..900cac17438460544878c9ee4ff4996fae5df8dc 100644 (file)
@@ -7,7 +7,7 @@
  *  of special functions or implement the interface to the bignum package. */
 
 /*
- *  GiNaC Copyright (C) 1999-2019 Johannes Gutenberg University Mainz, Germany
+ *  GiNaC Copyright (C) 1999-2024 Johannes Gutenberg University Mainz, Germany
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
 #include "numeric.h"
 #include "ex.h"
 #include "operators.h"
@@ -477,7 +473,7 @@ static inline bool coerce(T1& dst, const T2& arg);
 /** 
  * @brief Check if CLN integer can be converted into int
  *
- * @sa http://www.ginac.de/pipermail/cln-list/2006-October/000248.html
+ * @sa https://www.ginac.de/pipermail/cln-list/2006-October/000248.html
  */
 template<>
 inline bool coerce<int, cln::cl_I>(int& dst, const cln::cl_I& arg)
@@ -2142,8 +2138,10 @@ const numeric doublefactorial(const numeric &n)
 
 /** The Binomial coefficients.  It computes the binomial coefficients.  For
  *  integer n and k and positive n this is the number of ways of choosing k
- *  objects from n distinct objects.  If n is negative, the formula
- *  binomial(n,k) == (-1)^k*binomial(k-n-1,k) is used to compute the result. */
+ *  objects from n distinct objects.  If n is a negative integer, the formula
+ *  binomial(n,k) == (-1)^k*binomial(k-n-1,k) (if k>=0)
+ *  binomial(n,k) == (-1)^(n-k)*binomial(-k-1,n-k) (otherwise)
+ *  is used to compute the result. */
 const numeric binomial(const numeric &n, const numeric &k)
 {
        if (n.is_integer() && k.is_integer()) {
@@ -2153,7 +2151,10 @@ const numeric binomial(const numeric &n, const numeric &k)
                        else
                                return *_num0_p;
                } else {
-                       return _num_1_p->power(k)*binomial(k-n-(*_num1_p),k);
+                       if (k.is_nonneg_integer())
+                               return _num_1_p->power(k)*binomial(k-n-(*_num1_p), k);
+                       else
+                               return _num_1_p->power(n-k)*binomial(-k-(*_num1_p), n-k);
                }
        }