[GiNaC-devel] [PATCH 4/8] Li2, zeta, sqrt, abs, gcd, etc.: explicitly convert return value to numeric.

Alexei Sheplyakov varg at theor.jinr.ru
Wed Mar 19 10:26:52 CET 2008


Implicit conversion from cl_N to numeric considered harmful, part 4.

---
 ginac/numeric.cpp |   61 ++++++++++++++++++++++++++++++----------------------
 1 files changed, 35 insertions(+), 26 deletions(-)

diff --git a/ginac/numeric.cpp b/ginac/numeric.cpp
index 0f1b394..a06be42 100644
--- a/ginac/numeric.cpp
+++ b/ginac/numeric.cpp
@@ -1611,24 +1611,24 @@ static cln::cl_N Li2_projection(const cln::cl_N &x,
 	return Li2_series(x, prec);
 }
 
+
 /** Numeric evaluation of Dilogarithm.  The domain is the entire complex plane,
  *  the branch cut lies along the positive real axis, starting at 1 and
  *  continuous with quadrant IV.
  *
  *  @return  arbitrary precision numerical Li2(x). */
-const numeric Li2(const numeric &x)
+const cln::cl_N Li2_(const cln::cl_N& value)
 {
-	if (x.is_zero())
-		return *_num0_p;
+	if (zerop(value))
+		return 0;
 	
 	// what is the desired float format?
 	// first guess: default format
 	cln::float_format_t prec = cln::default_float_format;
-	const cln::cl_N value = x.to_cl_N();
 	// second guess: the argument's format
-	if (!x.real().is_rational())
+	if (!instanceof(realpart(value), cln::cl_RA_ring))
 		prec = cln::float_format(cln::the<cln::cl_F>(cln::realpart(value)));
-	else if (!x.imag().is_rational())
+	else if (!instanceof(imagpart(value), cln::cl_RA_ring))
 		prec = cln::float_format(cln::the<cln::cl_F>(cln::imagpart(value)));
 	
 	if (value==1)  // may cause trouble with log(1-x)
@@ -1640,7 +1640,16 @@ const numeric Li2(const numeric &x)
 		       - cln::zeta(2, prec)
 		       - Li2_projection(cln::recip(value), prec));
 	else
-		return Li2_projection(x.to_cl_N(), prec);
+		return Li2_projection(value, prec);
+}
+
+const numeric Li2(const numeric &x)
+{
+	const cln::cl_N x_ = x.to_cl_N();
+	if (zerop(x_))
+		return *_num0_p;
+	const cln::cl_N result = Li2_(x_);
+	return numeric(result);
 }
 
 
@@ -1656,7 +1665,7 @@ const numeric zeta(const numeric &x)
 	if (x.is_real()) {
 		const int aux = (int)(cln::double_approx(cln::the<cln::cl_R>(x.to_cl_N())));
 		if (cln::zerop(x.to_cl_N()-aux))
-			return cln::zeta(aux);
+			return numeric(cln::zeta(aux));
 	}
 	throw dunno();
 }
@@ -2219,7 +2228,7 @@ const numeric fibonacci(const numeric &n)
 /** Absolute value. */
 const numeric abs(const numeric& x)
 {
-	return cln::abs(x.to_cl_N());
+	return numeric(cln::abs(x.to_cl_N()));
 }
 
 
@@ -2233,8 +2242,8 @@ const numeric abs(const numeric& x)
 const numeric mod(const numeric &a, const numeric &b)
 {
 	if (a.is_integer() && b.is_integer())
-		return cln::mod(cln::the<cln::cl_I>(a.to_cl_N()),
-		                cln::the<cln::cl_I>(b.to_cl_N()));
+		return numeric(cln::mod(cln::the<cln::cl_I>(a.to_cl_N()),
+		                cln::the<cln::cl_I>(b.to_cl_N())));
 	else
 		return *_num0_p;
 }
@@ -2248,8 +2257,8 @@ const numeric smod(const numeric &a, const numeric &b)
 {
 	if (a.is_integer() && b.is_integer()) {
 		const cln::cl_I b2 = cln::ceiling1(cln::the<cln::cl_I>(b.to_cl_N()) >> 1) - 1;
-		return cln::mod(cln::the<cln::cl_I>(a.to_cl_N()) + b2,
-		                cln::the<cln::cl_I>(b.to_cl_N())) - b2;
+		return numeric(cln::mod(cln::the<cln::cl_I>(a.to_cl_N()) + b2,
+		                cln::the<cln::cl_I>(b.to_cl_N())) - b2);
 	} else
 		return *_num0_p;
 }
@@ -2267,8 +2276,8 @@ const numeric irem(const numeric &a, const numeric &b)
 	if (b.is_zero())
 		throw std::overflow_error("numeric::irem(): division by zero");
 	if (a.is_integer() && b.is_integer())
-		return cln::rem(cln::the<cln::cl_I>(a.to_cl_N()),
-		                cln::the<cln::cl_I>(b.to_cl_N()));
+		return numeric(cln::rem(cln::the<cln::cl_I>(a.to_cl_N()),
+		                cln::the<cln::cl_I>(b.to_cl_N())));
 	else
 		return *_num0_p;
 }
@@ -2289,8 +2298,8 @@ const numeric irem(const numeric &a, const numeric &b, numeric &q)
 	if (a.is_integer() && b.is_integer()) {
 		const cln::cl_I_div_t rem_quo = cln::truncate2(cln::the<cln::cl_I>(a.to_cl_N()),
 		                                               cln::the<cln::cl_I>(b.to_cl_N()));
-		q = rem_quo.quotient;
-		return rem_quo.remainder;
+		q = numeric(rem_quo.quotient);
+		return numeric(rem_quo.remainder);
 	} else {
 		q = *_num0_p;
 		return *_num0_p;
@@ -2308,8 +2317,8 @@ const numeric iquo(const numeric &a, const numeric &b)
 	if (b.is_zero())
 		throw std::overflow_error("numeric::iquo(): division by zero");
 	if (a.is_integer() && b.is_integer())
-		return cln::truncate1(cln::the<cln::cl_I>(a.to_cl_N()),
-	                          cln::the<cln::cl_I>(b.to_cl_N()));
+		return numeric(cln::truncate1(cln::the<cln::cl_I>(a.to_cl_N()),
+	                          cln::the<cln::cl_I>(b.to_cl_N())));
 	else
 		return *_num0_p;
 }
@@ -2329,7 +2338,7 @@ const numeric iquo(const numeric &a, const numeric &b, numeric &r)
 	if (a.is_integer() && b.is_integer()) {
 		const cln::cl_I_div_t rem_quo = cln::truncate2(cln::the<cln::cl_I>(a.to_cl_N()),
 		                                               cln::the<cln::cl_I>(b.to_cl_N()));
-		r = rem_quo.remainder;
+		r = numeric(rem_quo.remainder);
 		return rem_quo.quotient;
 	} else {
 		r = *_num0_p;
@@ -2345,8 +2354,8 @@ const numeric iquo(const numeric &a, const numeric &b, numeric &r)
 const numeric gcd(const numeric &a, const numeric &b)
 {
 	if (a.is_integer() && b.is_integer())
-		return cln::gcd(cln::the<cln::cl_I>(a.to_cl_N()),
-		                cln::the<cln::cl_I>(b.to_cl_N()));
+		return numeric(cln::gcd(cln::the<cln::cl_I>(a.to_cl_N()),
+		                cln::the<cln::cl_I>(b.to_cl_N())));
 	else
 		return *_num1_p;
 }
@@ -2359,8 +2368,8 @@ const numeric gcd(const numeric &a, const numeric &b)
 const numeric lcm(const numeric &a, const numeric &b)
 {
 	if (a.is_integer() && b.is_integer())
-		return cln::lcm(cln::the<cln::cl_I>(a.to_cl_N()),
-		                cln::the<cln::cl_I>(b.to_cl_N()));
+		return numeric(cln::lcm(cln::the<cln::cl_I>(a.to_cl_N()),
+		                cln::the<cln::cl_I>(b.to_cl_N())));
 	else
 		return a.mul(b);
 }
@@ -2376,7 +2385,7 @@ const numeric lcm(const numeric &a, const numeric &b)
  *  where imag(x)>0. */
 const numeric sqrt(const numeric &x)
 {
-	return cln::sqrt(x.to_cl_N());
+	return numeric(cln::sqrt(x.to_cl_N()));
 }
 
 
@@ -2386,7 +2395,7 @@ const numeric isqrt(const numeric &x)
 	if (x.is_integer()) {
 		cln::cl_I root;
 		cln::isqrt(cln::the<cln::cl_I>(x.to_cl_N()), &root);
-		return root;
+		return numeric(root);
 	} else
 		return *_num0_p;
 }
-- 
1.5.4.2


-- 
All science is either physics or stamp collecting.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: Digital signature
Url : http://www.cebix.net/pipermail/ginac-devel/attachments/20080319/bb24c833/attachment-0001.sig 


More information about the GiNaC-devel mailing list