* 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-2009 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
#include "config.h"
-#include <vector>
-#include <stdexcept>
-#include <string>
-#include <sstream>
-#include <limits>
-
#include "numeric.h"
#include "ex.h"
#include "operators.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
return x;
}
-numeric::numeric(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
+void numeric::read_archive(const archive_node &n, lst &sym_lst)
{
+ inherited::read_archive(n, sym_lst);
value = 0;
// Read number as string
}
setflag(status_flags::evaluated | status_flags::expanded);
}
+GINAC_BIND_UNARCHIVER(numeric);
static void write_real_float(std::ostream& s, const cln::cl_R& n)
{
n.add_string("number", s.str());
}
-DEFAULT_UNARCHIVE(numeric)
-
//////////
// functions overriding virtual functions from base classes
//////////
// 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);
/** 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;
}