]> www.ginac.de Git - ginac.git/blobdiff - ginac/numeric.cpp
- Changed policy: look for cln/cln.h instead of CLN/cln.h, reflecting an
[ginac.git] / ginac / numeric.cpp
index c0a2051b0ee311967bf29a01a80cd47eb8628ce0..c23d46a2408700b83b78fd541c59b516cd0091b6 100644 (file)
 
 #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
@@ -48,6 +72,8 @@ namespace GiNaC {
 // 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
@@ -110,7 +136,7 @@ void numeric::destroy(bool call_parent)
 
 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:
@@ -122,7 +148,7 @@ numeric::numeric(int i) : basic(TINFO_numeric)
 
 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:
@@ -134,7 +160,7 @@ numeric::numeric(unsigned int i) : basic(TINFO_numeric)
 
 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|
@@ -143,7 +169,7 @@ numeric::numeric(long i) : basic(TINFO_numeric)
 
 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|
@@ -155,7 +181,7 @@ numeric::numeric(unsigned long i) : basic(TINFO_numeric)
  *  @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);
@@ -167,7 +193,7 @@ numeric::numeric(long numer, long denom) : basic(TINFO_numeric)
 
 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:
@@ -180,7 +206,7 @@ numeric::numeric(double d) : basic(TINFO_numeric)
 
 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
@@ -194,13 +220,67 @@ numeric::numeric(char const *s) : basic(TINFO_numeric)
  *  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
 //////////
@@ -1370,7 +1450,7 @@ _numeric_digits::_numeric_digits()
 {
     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)