#include <vector>
#include <stdexcept>
+#include <string>
+#include <strstream> //!!
#include "numeric.h"
#include "ex.h"
#include "config.h"
+#include "archive.h"
#include "debugmsg.h"
#include "utils.h"
// CLN should not pollute the global namespace, hence we include it here
-// instead of in some header file where it would propagate to other parts:
+// instead of in some header file where it would propagate to other parts.
+// Also, we only need a subset of CLN, so we don't include the complete cln.h:
#ifdef HAVE_CLN_CLN_H
-#include <CLN/cln.h>
+#include <cln/cl_integer_io.h>
+#include <cln/cl_integer_ring.h>
+#include <cln/cl_rational_io.h>
+#include <cln/cl_rational_ring.h>
+#include <cln/cl_lfloat_class.h>
+#include <cln/cl_lfloat_io.h>
+#include <cln/cl_real_io.h>
+#include <cln/cl_real_ring.h>
+#include <cln/cl_complex_io.h>
+#include <cln/cl_complex_ring.h>
+#include <cln/cl_numtheory.h>
#else
-#include <cln.h>
+#include <cl_integer_io.h>
+#include <cl_integer_ring.h>
+#include <cl_rational_io.h>
+#include <cl_rational_ring.h>
+#include <cl_lfloat_class.h>
+#include <cl_lfloat_io.h>
+#include <cl_real_io.h>
+#include <cl_real_ring.h>
+#include <cl_complex_io.h>
+#include <cl_complex_ring.h>
+#include <cl_numtheory.h>
#endif
#ifndef NO_GINAC_NAMESPACE
// linker has no problems finding text symbols for numerator or denominator
//#define SANE_LINKER
+GINAC_IMPLEMENT_REGISTERED_CLASS(numeric, basic)
+
//////////
// default constructor, destructor, copy constructor assignment
// operator and helpers
numeric::numeric(int i) : basic(TINFO_numeric)
{
- debugmsg("const numericructor from int",LOGLEVEL_CONSTRUCT);
+ debugmsg("numeric constructor from int",LOGLEVEL_CONSTRUCT);
// Not the whole int-range is available if we don't cast to long
// first. This is due to the behaviour of the cl_I-ctor, which
// emphasizes efficiency:
numeric::numeric(unsigned int i) : basic(TINFO_numeric)
{
- debugmsg("const numericructor from uint",LOGLEVEL_CONSTRUCT);
+ debugmsg("numeric constructor from uint",LOGLEVEL_CONSTRUCT);
// Not the whole uint-range is available if we don't cast to ulong
// first. This is due to the behaviour of the cl_I-ctor, which
// emphasizes efficiency:
numeric::numeric(long i) : basic(TINFO_numeric)
{
- debugmsg("const numericructor from long",LOGLEVEL_CONSTRUCT);
+ debugmsg("numeric constructor from long",LOGLEVEL_CONSTRUCT);
value = new cl_I(i);
calchash();
setflag(status_flags::evaluated|
numeric::numeric(unsigned long i) : basic(TINFO_numeric)
{
- debugmsg("const numericructor from ulong",LOGLEVEL_CONSTRUCT);
+ debugmsg("numeric constructor from ulong",LOGLEVEL_CONSTRUCT);
value = new cl_I(i);
calchash();
setflag(status_flags::evaluated|
* @exception overflow_error (division by zero) */
numeric::numeric(long numer, long denom) : basic(TINFO_numeric)
{
- debugmsg("const numericructor from long/long",LOGLEVEL_CONSTRUCT);
+ debugmsg("numeric constructor from long/long",LOGLEVEL_CONSTRUCT);
if (!denom)
throw (std::overflow_error("division by zero"));
value = new cl_I(numer);
numeric::numeric(double d) : basic(TINFO_numeric)
{
- debugmsg("const numericructor from double",LOGLEVEL_CONSTRUCT);
+ debugmsg("numeric constructor from double",LOGLEVEL_CONSTRUCT);
// We really want to explicitly use the type cl_LF instead of the
// more general cl_F, since that would give us a cl_DF only which
// will not be promoted to cl_LF if overflow occurs:
numeric::numeric(char const *s) : basic(TINFO_numeric)
{ // MISSING: treatment of complex and ints and rationals.
- debugmsg("const numericructor from string",LOGLEVEL_CONSTRUCT);
+ debugmsg("numeric constructor from string",LOGLEVEL_CONSTRUCT);
if (strchr(s, '.'))
value = new cl_LF(s);
else
* only. */
numeric::numeric(cl_N const & z) : basic(TINFO_numeric)
{
- debugmsg("const numericructor from cl_N", LOGLEVEL_CONSTRUCT);
+ debugmsg("numeric constructor from cl_N", LOGLEVEL_CONSTRUCT);
value = new cl_N(z);
calchash();
setflag(status_flags::evaluated|
status_flags::hash_calculated);
}
+//////////
+// archiving
+//////////
+
+/** Construct object from archive_node. */
+numeric::numeric(const archive_node &n, const lst &sym_lst) : inherited(n, sym_lst)
+{
+ debugmsg("numeric constructor from archive_node", LOGLEVEL_CONSTRUCT);
+ value = new cl_N;
+#if 0 //!!
+ // This is how it should be implemented but we have no istringstream here...
+ string str;
+ if (n.find_string("number", str)) {
+ istringstream s(str);
+ s >> *value;
+ }
+#else
+ // Workaround for the above: read from strstream
+ string str;
+ if (n.find_string("number", str)) {
+ istrstream f(str.c_str(), str.size() + 1);
+ f >> *value;
+ }
+#endif
+ calchash();
+ setflag(status_flags::evaluated|
+ status_flags::hash_calculated);
+}
+
+/** Unarchive the object. */
+ex numeric::unarchive(const archive_node &n, const lst &sym_lst)
+{
+ return (new numeric(n, sym_lst))->setflag(status_flags::dynallocated);
+}
+
+/** Archive the object. */
+void numeric::archive(archive_node &n) const
+{
+ inherited::archive(n);
+#if 0 //!!
+ // This is how it should be implemented but we have no ostringstream here...
+ ostringstream s;
+ s << *value;
+ n.add_string("number", s.str());
+#else
+ // Workaround for the above: write to strstream
+ char buf[1024];
+ ostrstream f(buf, 1024);
+ f << *value << ends;
+ string str(buf);
+ n.add_string("number", str);
+#endif
+}
+
//////////
// functions overriding virtual functions from bases classes
//////////
{
assert(!too_late);
too_late = true;
- cl_default_float_format = cl_float_format(17);
+ cl_default_float_format = cl_float_format(17);
}
_numeric_digits& _numeric_digits::operator=(long prec)