]> www.ginac.de Git - ginac.git/blobdiff - ginac/numeric.cpp
Improve (fix?) smod: now it really converts into symmetric representation...
[ginac.git] / ginac / numeric.cpp
index 1c9b4208f63cebbb2d79ceb563ad1bce4c6401bc..50d873a9f6c5ac0da255553db40f64fb14a75057 100644 (file)
@@ -2278,11 +2278,14 @@ const numeric fibonacci(const numeric &n)
        //      F(2n+2) = F(n+1)*(2*F(n) + F(n+1))
        if (n.is_zero())
                return *_num0_p;
-       if (n.is_negative())
-               if (n.is_even())
+       if (n.is_negative()) {
+               if (n.is_even()) {
                        return -fibonacci(-n);
-               else
+               }
+               else {
                        return fibonacci(-n);
+               }
+       }
        
        cln::cl_I u(0);
        cln::cl_I v(1);
@@ -2334,15 +2337,18 @@ const numeric mod(const numeric &a, const numeric &b)
 
 
 /** Modulus (in symmetric representation).
- *  Equivalent to Maple's mods.
  *
- *  @return a mod b in the range [-iquo(abs(b)-1,2), iquo(abs(b),2)]. */
-const numeric smod(const numeric &a, const numeric &b)
-{
-       if (a.is_integer() && b.is_integer()) {
-               const cln::cl_I b2 = cln::ceiling1(cln::the<cln::cl_I>(b.to_cl_N()) >> 1) - 1;
-               return numeric(cln::mod(cln::the<cln::cl_I>(a.to_cl_N()) + b2,
-                               cln::the<cln::cl_I>(b.to_cl_N())) - b2);
+ *  @return a mod b in the range [-iquo(abs(b),2), iquo(abs(b),2)]. */
+const numeric smod(const numeric &a_, const numeric &b_)
+{
+       if (a_.is_integer() && b_.is_integer()) {
+               const cln::cl_I a = cln::the<cln::cl_I>(a_.to_cl_N());
+               const cln::cl_I b = cln::the<cln::cl_I>(b_.to_cl_N());
+               const cln::cl_I b2 = b >> 1;
+               const cln::cl_I m = cln::mod(a, b);
+               const cln::cl_I m_b = m - b;
+               const cln::cl_I ret = m > b2 ? m_b : m;
+               return numeric(ret);
        } else
                return *_num0_p;
 }