* Its most important design principle is to completely hide the inner
* working of that other package from the user of GiNaC. It must either
* provide implementation of arithmetic operators and numerical evaluation
- * of special functions or implement the interface to the bignum package.
- *
+ * of special functions or implement the interface to the bignum package. */
+
+/*
* GiNaC Copyright (C) 1999 Johannes Gutenberg University Mainz, Germany
*
* This program is free software; you can redistribute it and/or modify
#include <vector>
#include <stdexcept>
-#include "ginac.h"
+#include "numeric.h"
+#include "ex.h"
#include "config.h"
+#include "debugmsg.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:
#include <cln.h>
#endif
+namespace GiNaC {
+
// linker has no problems finding text symbols for numerator or denominator
//#define SANE_LINKER
// public
/** default ctor. Numerically it initializes to an integer zero. */
-numeric::numeric() : basic(TINFO_NUMERIC)
+numeric::numeric() : basic(TINFO_numeric)
{
debugmsg("numeric default constructor", LOGLEVEL_CONSTRUCT);
value = new cl_N;
// public
-numeric::numeric(int i) : basic(TINFO_NUMERIC)
+numeric::numeric(int i) : basic(TINFO_numeric)
{
debugmsg("numeric constructor from int",LOGLEVEL_CONSTRUCT);
// Not the whole int-range is available if we don't cast to long
status_flags::hash_calculated);
}
-numeric::numeric(unsigned int i) : basic(TINFO_NUMERIC)
+numeric::numeric(unsigned int i) : basic(TINFO_numeric)
{
debugmsg("numeric constructor from uint",LOGLEVEL_CONSTRUCT);
// Not the whole uint-range is available if we don't cast to ulong
status_flags::hash_calculated);
}
-numeric::numeric(long i) : basic(TINFO_NUMERIC)
+numeric::numeric(long i) : basic(TINFO_numeric)
{
debugmsg("numeric constructor from long",LOGLEVEL_CONSTRUCT);
value = new cl_I(i);
status_flags::hash_calculated);
}
-numeric::numeric(unsigned long i) : basic(TINFO_NUMERIC)
+numeric::numeric(unsigned long i) : basic(TINFO_numeric)
{
debugmsg("numeric constructor from ulong",LOGLEVEL_CONSTRUCT);
value = new cl_I(i);
/** Ctor for rational numerics a/b.
*
* @exception overflow_error (division by zero) */
-numeric::numeric(long numer, long denom) : basic(TINFO_NUMERIC)
+numeric::numeric(long numer, long denom) : basic(TINFO_numeric)
{
debugmsg("numeric constructor from long/long",LOGLEVEL_CONSTRUCT);
if (!denom)
status_flags::hash_calculated);
}
-numeric::numeric(double d) : basic(TINFO_NUMERIC)
+numeric::numeric(double d) : basic(TINFO_numeric)
{
debugmsg("numeric constructor from double",LOGLEVEL_CONSTRUCT);
// We really want to explicitly use the type cl_LF instead of the
status_flags::hash_calculated);
}
-numeric::numeric(char const *s) : basic(TINFO_NUMERIC)
+numeric::numeric(char const *s) : basic(TINFO_numeric)
{ // MISSING: treatment of complex and ints and rationals.
debugmsg("numeric constructor from string",LOGLEVEL_CONSTRUCT);
if (strchr(s, '.'))
/** Ctor from CLN types. This is for the initiated user or internal use
* only. */
-numeric::numeric(cl_N const & z) : basic(TINFO_NUMERIC)
+numeric::numeric(cl_N const & z) : basic(TINFO_numeric)
{
debugmsg("numeric constructor from cl_N", LOGLEVEL_CONSTRUCT);
value = new cl_N(z);
type_info const & typeid_numeric=typeid(some_numeric);
/** Imaginary unit. This is not a constant but a numeric since we are
* natively handing complex numbers anyways. */
-const numeric I = (complex(cl_I(0),cl_I(1)));
+const numeric I = numeric(complex(cl_I(0),cl_I(1)));
//////////
// global functions
* @return arbitrary precision numerical exp(x). */
numeric exp(numeric const & x)
{
- return exp(*x.value); // -> CLN
+ return ::exp(*x.value); // -> CLN
}
/** Natural logarithm.
{
if (z.is_zero())
throw (std::overflow_error("log(): logarithmic singularity"));
- return log(*z.value); // -> CLN
+ return ::log(*z.value); // -> CLN
}
/** Numeric sine (trigonometric function).
* @return arbitrary precision numerical sin(x). */
numeric sin(numeric const & x)
{
- return sin(*x.value); // -> CLN
+ return ::sin(*x.value); // -> CLN
}
/** Numeric cosine (trigonometric function).
* @return arbitrary precision numerical cos(x). */
numeric cos(numeric const & x)
{
- return cos(*x.value); // -> CLN
+ return ::cos(*x.value); // -> CLN
}
/** Numeric tangent (trigonometric function).
* @return arbitrary precision numerical tan(x). */
numeric tan(numeric const & x)
{
- return tan(*x.value); // -> CLN
+ return ::tan(*x.value); // -> CLN
}
/** Numeric inverse sine (trigonometric function).
* @return arbitrary precision numerical asin(x). */
numeric asin(numeric const & x)
{
- return asin(*x.value); // -> CLN
+ return ::asin(*x.value); // -> CLN
}
/** Numeric inverse cosine (trigonometric function).
* @return arbitrary precision numerical acos(x). */
numeric acos(numeric const & x)
{
- return acos(*x.value); // -> CLN
+ return ::acos(*x.value); // -> CLN
}
/** Arcustangents.
x.real().is_zero() &&
!abs(x.imag()).is_equal(numONE()))
throw (std::overflow_error("atan(): logarithmic singularity"));
- return atan(*x.value); // -> CLN
+ return ::atan(*x.value); // -> CLN
}
/** Arcustangents.
numeric atan(numeric const & y, numeric const & x)
{
if (x.is_real() && y.is_real())
- return atan(realpart(*x.value), realpart(*y.value)); // -> CLN
+ return ::atan(realpart(*x.value), realpart(*y.value)); // -> CLN
else
throw (std::invalid_argument("numeric::atan(): complex argument"));
}
* @return arbitrary precision numerical sinh(x). */
numeric sinh(numeric const & x)
{
- return sinh(*x.value); // -> CLN
+ return ::sinh(*x.value); // -> CLN
}
/** Numeric hyperbolic cosine (trigonometric function).
* @return arbitrary precision numerical cosh(x). */
numeric cosh(numeric const & x)
{
- return cosh(*x.value); // -> CLN
+ return ::cosh(*x.value); // -> CLN
}
/** Numeric hyperbolic tangent (trigonometric function).
* @return arbitrary precision numerical tanh(x). */
numeric tanh(numeric const & x)
{
- return tanh(*x.value); // -> CLN
+ return ::tanh(*x.value); // -> CLN
}
/** Numeric inverse hyperbolic sine (trigonometric function).
* @return arbitrary precision numerical asinh(x). */
numeric asinh(numeric const & x)
{
- return asinh(*x.value); // -> CLN
+ return ::asinh(*x.value); // -> CLN
}
/** Numeric inverse hyperbolic cosine (trigonometric function).
* @return arbitrary precision numerical acosh(x). */
numeric acosh(numeric const & x)
{
- return acosh(*x.value); // -> CLN
+ return ::acosh(*x.value); // -> CLN
}
/** Numeric inverse hyperbolic tangent (trigonometric function).
* @return arbitrary precision numerical atanh(x). */
numeric atanh(numeric const & x)
{
- return atanh(*x.value); // -> CLN
+ return ::atanh(*x.value); // -> CLN
}
/** The gamma function.
throw (std::range_error("numeric::factorial(): argument must be integer >= 0"));
}
- return numeric(factorial(nn.to_int())); // -> CLN
+ return numeric(::factorial(nn.to_int())); // -> CLN
}
/** The double factorial combinatorial function. (Scarcely used, but still
numeric binomial(numeric const & n, numeric const & k)
{
if (n.is_nonneg_integer() && k.is_nonneg_integer()) {
- return numeric(binomial(n.to_int(),k.to_int())); // -> CLN
+ return numeric(::binomial(n.to_int(),k.to_int())); // -> CLN
} else {
// should really be gamma(n+1)/(gamma(r+1)/gamma(n-r+1)
return numeric(0);
/** Absolute value. */
numeric abs(numeric const & x)
{
- return abs(*x.value); // -> CLN
+ return ::abs(*x.value); // -> CLN
}
/** Modulus (in positive representation).
numeric mod(numeric const & a, numeric const & b)
{
if (a.is_integer() && b.is_integer()) {
- return mod(The(cl_I)(*a.value), The(cl_I)(*b.value)); // -> CLN
+ return ::mod(The(cl_I)(*a.value), The(cl_I)(*b.value)); // -> CLN
}
else {
return numZERO(); // Throw?
{
if (a.is_integer() && b.is_integer()) {
cl_I b2 = The(cl_I)(ceiling1(The(cl_I)(*b.value) / 2)) - 1;
- return mod(The(cl_I)(*a.value) + b2, The(cl_I)(*b.value)) - b2;
+ return ::mod(The(cl_I)(*a.value) + b2, The(cl_I)(*b.value)) - b2;
} else {
return numZERO(); // Throw?
}
numeric irem(numeric const & a, numeric const & b)
{
if (a.is_integer() && b.is_integer()) {
- return rem(The(cl_I)(*a.value), The(cl_I)(*b.value)); // -> CLN
+ return ::rem(The(cl_I)(*a.value), The(cl_I)(*b.value)); // -> CLN
}
else {
return numZERO(); // Throw?
* where imag(z)>0. */
numeric sqrt(numeric const & z)
{
- return sqrt(*z.value); // -> CLN
+ return ::sqrt(*z.value); // -> CLN
}
/** Integer numeric square root. */
{
if (x.is_integer()) {
cl_I root;
- isqrt(The(cl_I)(*x.value), &root); // -> CLN
+ ::isqrt(The(cl_I)(*x.value), &root); // -> CLN
return root;
} else
return numZERO(); // Throw?
numeric gcd(numeric const & a, numeric const & b)
{
if (a.is_integer() && b.is_integer())
- return gcd(The(cl_I)(*a.value), The(cl_I)(*b.value)); // -> CLN
+ return ::gcd(The(cl_I)(*a.value), The(cl_I)(*b.value)); // -> CLN
else
return numONE();
}
numeric lcm(numeric const & a, numeric const & b)
{
if (a.is_integer() && b.is_integer())
- return lcm(The(cl_I)(*a.value), The(cl_I)(*b.value)); // -> CLN
+ return ::lcm(The(cl_I)(*a.value), The(cl_I)(*b.value)); // -> CLN
else
return *a.value * *b.value;
}
/** Accuracy in decimal digits. Only object of this type! Can be set using
* assignment from C++ unsigned ints and evaluated like any built-in type. */
_numeric_digits Digits;
+
+} // namespace GiNaC