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);
{
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);
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);
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 {
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
}
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;
}
}
-/** The gamma function.
+/** 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);
/** 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
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();
}
-/** Floating point evaluation of Euler's constant Gamma. */
-ex EulerGammaEvalf(void)
+/** Floating point evaluation of Euler's constant gamma. */
+ex EulerEvalf(void)
{
return numeric(::cl_eulerconst(cl_default_float_format)); // -> CLN
}