]> www.ginac.de Git - ginac.git/blobdiff - ginac/numeric.cpp
- introduced info_flag::algebraic.
[ginac.git] / ginac / numeric.cpp
index c0649f6f70b550987df6177efcea50f44b0e8f9d..3652f4d47e8346c319c23c8277b4bbddf8b84376 100644 (file)
@@ -221,12 +221,12 @@ numeric::numeric(double d) : basic(TINFO_numeric)
 
 
 numeric::numeric(const char *s) : basic(TINFO_numeric)
-{   // MISSING: treatment of complex and ints and rationals.
+{   // MISSING: treatment of complex numbers
     debugmsg("numeric constructor from string",LOGLEVEL_CONSTRUCT);
     if (strchr(s, '.'))
         value = new cl_LF(s);
     else
-        value = new cl_I(s);
+        value = new cl_R(s);
     calchash();
     setflag(status_flags::evaluated|
             status_flags::hash_calculated);
@@ -252,16 +252,19 @@ numeric::numeric(const archive_node &n, const lst &sym_lst) : inherited(n, sym_l
 {
     debugmsg("numeric constructor from archive_node", LOGLEVEL_CONSTRUCT);
     value = new cl_N;
-#ifdef HAVE_SSTREAM
+
     // Read number as string
     string str;
     if (n.find_string("number", str)) {
+#ifdef HAVE_SSTREAM
         istringstream s(str);
+#else
+               istrstream s(str.c_str(), str.size() + 1);
+#endif
         cl_idecoded_float re, im;
         char c;
         s.get(c);
         switch (c) {
-            case 'N':    // Ordinary number
             case 'R':    // Integer-decoded real number
                 s >> re.sign >> re.mantissa >> re.exponent;
                 *value = re.sign * re.mantissa * ::expt(cl_float(2.0, cl_default_float_format), re.exponent);
@@ -278,32 +281,6 @@ numeric::numeric(const archive_node &n, const lst &sym_lst) : inherited(n, sym_l
                 break;
         }
     }
-#else
-    // Read number as string
-    string str;
-    if (n.find_string("number", str)) {
-        istrstream f(str.c_str(), str.size() + 1);
-        cl_idecoded_float re, im;
-        char c;
-        f.get(c);
-        switch (c) {
-            case 'R':    // Integer-decoded real number
-                f >> re.sign >> re.mantissa >> re.exponent;
-                *value = re.sign * re.mantissa * ::expt(cl_float(2.0, cl_default_float_format), re.exponent);
-                break;
-            case 'C':    // Integer-decoded complex number
-                f >> re.sign >> re.mantissa >> re.exponent;
-                f >> im.sign >> im.mantissa >> im.exponent;
-                *value = ::complex(re.sign * re.mantissa * ::expt(cl_float(2.0, cl_default_float_format), re.exponent),
-                                 im.sign * im.mantissa * ::expt(cl_float(2.0, cl_default_float_format), im.exponent));
-                break;
-            default:   // Ordinary number
-                               f.putback(c);
-                f >> *value;
-                               break;
-        }
-    }
-#endif
     calchash();
     setflag(status_flags::evaluated|
             status_flags::hash_calculated);
@@ -319,9 +296,14 @@ ex numeric::unarchive(const archive_node &n, const lst &sym_lst)
 void numeric::archive(archive_node &n) const
 {
     inherited::archive(n);
-#ifdef HAVE_SSTREAM
+
     // Write number as string
+#ifdef HAVE_SSTREAM
     ostringstream s;
+#else
+    char buf[1024];
+    ostrstream s(buf, 1024);
+#endif
     if (this->is_crational())
         s << *value;
     else {
@@ -339,30 +321,12 @@ void numeric::archive(archive_node &n) const
             s << im.sign << " " << im.mantissa << " " << im.exponent;
         }
     }
+#ifdef HAVE_SSTREAM
     n.add_string("number", s.str());
 #else
-    // Write number as string
-    char buf[1024];
-    ostrstream f(buf, 1024);
-    if (this->is_crational())
-        f << *value << ends;
-    else {
-        // Non-rational numbers are written in an integer-decoded format
-        // to preserve the precision
-        if (this->is_real()) {
-            cl_idecoded_float re = integer_decode_float(The(cl_F)(*value));
-            f << "R";
-            f << re.sign << " " << re.mantissa << " " << re.exponent << ends;
-        } else {
-            cl_idecoded_float re = integer_decode_float(The(cl_F)(::realpart(*value)));
-            cl_idecoded_float im = integer_decode_float(The(cl_F)(::imagpart(*value)));
-            f << "C";
-            f << re.sign << " " << re.mantissa << " " << re.exponent << " ";
-            f << im.sign << " " << im.mantissa << " " << im.exponent << ends;
-        }
-    }
-    string str(buf);
-    n.add_string("number", str);
+       s << ends;
+       string str(buf);
+       n.add_string("number", str);
 #endif
 }
 
@@ -525,42 +489,44 @@ void numeric::printcsrc(ostream & os, unsigned type, unsigned upper_precedence)
 bool numeric::info(unsigned inf) const
 {
     switch (inf) {
-    case info_flags::numeric:
-    case info_flags::polynomial:
-    case info_flags::rational_function:
-        return true;
-    case info_flags::real:
-        return is_real();
-    case info_flags::rational:
-    case info_flags::rational_polynomial:
-        return is_rational();
-    case info_flags::crational:
-    case info_flags::crational_polynomial:
-        return is_crational();
-    case info_flags::integer:
-    case info_flags::integer_polynomial:
-        return is_integer();
-    case info_flags::cinteger:
-    case info_flags::cinteger_polynomial:
-        return is_cinteger();
-    case info_flags::positive:
-        return is_positive();
-    case info_flags::negative:
-        return is_negative();
-    case info_flags::nonnegative:
-        return !is_negative();
-    case info_flags::posint:
-        return is_pos_integer();
-    case info_flags::negint:
-        return is_integer() && is_negative();
-    case info_flags::nonnegint:
-        return is_nonneg_integer();
-    case info_flags::even:
-        return is_even();
-    case info_flags::odd:
-        return is_odd();
-    case info_flags::prime:
-        return is_prime();
+        case info_flags::numeric:
+        case info_flags::polynomial:
+        case info_flags::rational_function:
+            return true;
+        case info_flags::real:
+            return is_real();
+        case info_flags::rational:
+        case info_flags::rational_polynomial:
+            return is_rational();
+        case info_flags::crational:
+        case info_flags::crational_polynomial:
+            return is_crational();
+        case info_flags::integer:
+        case info_flags::integer_polynomial:
+            return is_integer();
+        case info_flags::cinteger:
+        case info_flags::cinteger_polynomial:
+            return is_cinteger();
+        case info_flags::positive:
+            return is_positive();
+        case info_flags::negative:
+            return is_negative();
+        case info_flags::nonnegative:
+            return !is_negative();
+        case info_flags::posint:
+            return is_pos_integer();
+        case info_flags::negint:
+            return is_integer() && is_negative();
+        case info_flags::nonnegint:
+            return is_nonneg_integer();
+        case info_flags::even:
+            return is_even();
+        case info_flags::odd:
+            return is_odd();
+        case info_flags::prime:
+            return is_prime();
+        case info_flags::algebraic:
+            return !is_real();
     }
     return false;
 }
@@ -1384,9 +1350,16 @@ const numeric zeta(const numeric & x)
 
 /** The Gamma function.
  *  This is only a stub! */
-const numeric Gamma(const numeric & x)
+const numeric lgamma(const numeric & x)
+{
+    clog << "lgamma(" << x
+         << "): Does anybody know good way to calculate this numerically?"
+         << endl;
+    return numeric(0);
+}
+const numeric tgamma(const numeric & x)
 {
-    clog << "Gamma(" << x
+    clog << "tgamma(" << x
          << "): Does anybody know good way to calculate this numerically?"
          << endl;
     return numeric(0);
@@ -1428,7 +1401,7 @@ const numeric factorial(const numeric & n)
 
 
 /** The double factorial combinatorial function.  (Scarcely used, but still
- *  useful in cases, like for exact results of Gamma(n+1/2) for instance.)
+ *  useful in cases, like for exact results of tgamma(n+1/2) for instance.)
  *
  *  @param n  integer argument >= -1
  *  @return n!! == n * (n-2) * (n-4) * ... * ({1|2}) with 0!! == (-1)!! == 1
@@ -1482,13 +1455,13 @@ const numeric bernoulli(const numeric & nn)
         return numeric(-1,2);
     if (nn.is_odd())
         return _num0();
-    // Until somebody has the Blues and comes up with a much better idea and
+    // Until somebody has the blues and comes up with a much better idea and
     // codes it (preferably in CLN) we make this a remembering function which
     // computes its results using the defining formula
     // B(nn) == - 1/(nn+1) * sum_{k=0}^{nn-1}(binomial(nn+1,k)*B(k))
     // whith B(0) == 1.
-    // Be warned, though: the Bernoulli numbers are probably computationally 
-    // very expensive anyhow and you shouldn't expect miracles to happen.
+    // Be warned, though: the Bernoulli numbers are computationally very
+    // expensive anyhow and you shouldn't expect miracles to happen.
     static vector<numeric> results;
     static int highest_result = -1;
     int n = nn.sub(_num2()).div(_num2()).to_int();
@@ -1731,8 +1704,8 @@ ex PiEvalf(void)
 }
 
 
-/** Floating point evaluation of Euler's constant Gamma. */
-ex gammaEvalf(void)
+/** Floating point evaluation of Euler's constant gamma. */
+ex EulerEvalf(void)
 { 
     return numeric(::cl_eulerconst(cl_default_float_format));  // -> CLN
 }