]> www.ginac.de Git - ginac.git/blobdiff - ginac/numeric.cpp
Update copyright statements.
[ginac.git] / ginac / numeric.cpp
index 91721e1b6a55a5e8a6a69ae5d93f4e4d0d8946a7..bc6fc8307bd4d36e4e3d6f2e158862b8319da793 100644 (file)
@@ -7,7 +7,7 @@
  *  of special functions or implement the interface to the bignum package. */
 
 /*
- *  GiNaC Copyright (C) 1999-2008 Johannes Gutenberg University Mainz, Germany
+ *  GiNaC Copyright (C) 1999-2014 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"
-
-#include <vector>
-#include <stdexcept>
-#include <string>
-#include <sstream>
-#include <limits>
+#endif
 
 #include "numeric.h"
 #include "ex.h"
 #include "tostring.h"
 #include "utils.h"
 
+#include <limits>
+#include <sstream>
+#include <stdexcept>
+#include <string>
+#include <vector>
+
 // CLN should pollute the global namespace as little as possible.  Hence, we
 // include most of it here and include only the part needed for properly
 // declaring cln::cl_number in numeric.h.  This can only be safely done in
@@ -700,7 +702,7 @@ bool numeric::info(unsigned inf) const
                case info_flags::negative:
                        return is_negative();
                case info_flags::nonnegative:
-                       return !is_negative();
+                       return is_zero() || is_positive();
                case info_flags::posint:
                        return is_pos_integer();
                case info_flags::negint:
@@ -2337,15 +2339,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;
 }