* of special functions or implement the interface to the bignum package. */
/*
- * GiNaC Copyright (C) 1999-2007 Johannes Gutenberg University Mainz, Germany
+ * GiNaC Copyright (C) 1999-2008 Johannes Gutenberg University Mainz, Germany
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
}
}
+template<typename T1, typename T2>
+static inline bool coerce(T1& dst, const T2& arg);
+
+/**
+ * @brief Check if CLN integer can be converted into int
+ *
+ * @sa http://www.ginac.de/pipermail/cln-list/2006-October/000248.html
+ */
+template<>
+inline bool coerce<int, cln::cl_I>(int& dst, const cln::cl_I& arg)
+{
+ static const cln::cl_I cl_max_int =
+ (cln::cl_I)(long)(std::numeric_limits<int>::max());
+ static const cln::cl_I cl_min_int =
+ (cln::cl_I)(long)(std::numeric_limits<int>::min());
+ if ((arg >= cl_min_int) && (arg <= cl_max_int)) {
+ dst = cl_I_to_int(arg);
+ return true;
+ }
+ return false;
+}
+
+template<>
+inline bool coerce<unsigned int, cln::cl_I>(unsigned int& dst, const cln::cl_I& arg)
+{
+ static const cln::cl_I cl_max_uint =
+ (cln::cl_I)(unsigned long)(std::numeric_limits<unsigned int>::max());
+ if ((! minusp(arg)) && (arg <= cl_max_uint)) {
+ dst = cl_I_to_uint(arg);
+ return true;
+ }
+ return false;
+}
+
/** Helper function to print real number in C++ source format using cl_N types.
*
* @see numeric::print() */
{
if (cln::instanceof(x, cln::cl_I_ring)) {
- // Integer number
- c.s << "cln::cl_I(\"";
- print_real_number(c, x);
- c.s << "\")";
-
+ int dst;
+ // fixnum
+ if (coerce(dst, cln::the<cln::cl_I>(x))) {
+ // can be converted to native int
+ if (dst < 0)
+ c.s << "(-" << dst << ")";
+ else
+ c.s << dst;
+ } else {
+ // bignum
+ c.s << "cln::cl_I(\"";
+ print_real_number(c, x);
+ c.s << "\")";
+ }
} else if (cln::instanceof(x, cln::cl_RA_ring)) {
// Rational number
* @return arbitrary precision numerical exp(x). */
const numeric exp(const numeric &x)
{
- return cln::exp(x.to_cl_N());
+ return numeric(cln::exp(x.to_cl_N()));
}
{
if (x.is_zero())
throw pole_error("log(): logarithmic pole",0);
- return cln::log(x.to_cl_N());
+ return numeric(cln::log(x.to_cl_N()));
}
* @return arbitrary precision numerical sin(x). */
const numeric sin(const numeric &x)
{
- return cln::sin(x.to_cl_N());
+ return numeric(cln::sin(x.to_cl_N()));
}
* @return arbitrary precision numerical cos(x). */
const numeric cos(const numeric &x)
{
- return cln::cos(x.to_cl_N());
+ return numeric(cln::cos(x.to_cl_N()));
}
* @return arbitrary precision numerical tan(x). */
const numeric tan(const numeric &x)
{
- return cln::tan(x.to_cl_N());
+ return numeric(cln::tan(x.to_cl_N()));
}
* @return arbitrary precision numerical asin(x). */
const numeric asin(const numeric &x)
{
- return cln::asin(x.to_cl_N());
+ return numeric(cln::asin(x.to_cl_N()));
}
* @return arbitrary precision numerical acos(x). */
const numeric acos(const numeric &x)
{
- return cln::acos(x.to_cl_N());
+ return numeric(cln::acos(x.to_cl_N()));
}
x.real().is_zero() &&
abs(x.imag()).is_equal(*_num1_p))
throw pole_error("atan(): logarithmic pole",0);
- return cln::atan(x.to_cl_N());
+ return numeric(cln::atan(x.to_cl_N()));
}
if (x.is_zero() && y.is_zero())
return *_num0_p;
if (x.is_real() && y.is_real())
- return cln::atan(cln::the<cln::cl_R>(x.to_cl_N()),
- cln::the<cln::cl_R>(y.to_cl_N()));
+ return numeric(cln::atan(cln::the<cln::cl_R>(x.to_cl_N()),
+ cln::the<cln::cl_R>(y.to_cl_N())));
// Compute -I*log((x+I*y)/sqrt(x^2+y^2))
// == -I*log((x+I*y)/sqrt((x+I*y)*(x-I*y)))
// x-I*y==0 => y/x==-I, so this is a pole (we have x!=0).
throw pole_error("atan(): logarithmic pole",0);
}
- return cln::complex(0,-1)*cln::log(aux_p/cln::sqrt(aux_p*aux_m));
+ return numeric(cln::complex(0,-1)*cln::log(aux_p/cln::sqrt(aux_p*aux_m)));
}
* @return arbitrary precision numerical sinh(x). */
const numeric sinh(const numeric &x)
{
- return cln::sinh(x.to_cl_N());
+ return numeric(cln::sinh(x.to_cl_N()));
}
* @return arbitrary precision numerical cosh(x). */
const numeric cosh(const numeric &x)
{
- return cln::cosh(x.to_cl_N());
+ return numeric(cln::cosh(x.to_cl_N()));
}
* @return arbitrary precision numerical tanh(x). */
const numeric tanh(const numeric &x)
{
- return cln::tanh(x.to_cl_N());
+ return numeric(cln::tanh(x.to_cl_N()));
}
* @return arbitrary precision numerical asinh(x). */
const numeric asinh(const numeric &x)
{
- return cln::asinh(x.to_cl_N());
+ return numeric(cln::asinh(x.to_cl_N()));
}
* @return arbitrary precision numerical acosh(x). */
const numeric acosh(const numeric &x)
{
- return cln::acosh(x.to_cl_N());
+ return numeric(cln::acosh(x.to_cl_N()));
}
* @return arbitrary precision numerical atanh(x). */
const numeric atanh(const numeric &x)
{
- return cln::atanh(x.to_cl_N());
+ return numeric(cln::atanh(x.to_cl_N()));
}