]> www.ginac.de Git - ginac.git/blobdiff - ginac/numeric.cpp
- Complete revamp of methods in class matrix. Some redundant (and poor)
[ginac.git] / ginac / numeric.cpp
index 36b3551c9d64dac317c3a5f97f82bc42ea00b63c..bcf140d6bba31fa917ed86b1f76a4fe1ee8e88a9 100644 (file)
@@ -153,7 +153,8 @@ numeric::numeric(int i) : basic(TINFO_numeric)
     // emphasizes efficiency:
     value = new ::cl_I((long) i);
     calchash();
-    setflag(status_flags::evaluated|
+    setflag(status_flags::evaluated |
+            status_flags::expanded |
             status_flags::hash_calculated);
 }
 
@@ -166,7 +167,8 @@ numeric::numeric(unsigned int i) : basic(TINFO_numeric)
     // emphasizes efficiency:
     value = new ::cl_I((unsigned long)i);
     calchash();
-    setflag(status_flags::evaluated|
+    setflag(status_flags::evaluated |
+            status_flags::expanded |
             status_flags::hash_calculated);
 }
 
@@ -176,7 +178,8 @@ numeric::numeric(long i) : basic(TINFO_numeric)
     debugmsg("numeric constructor from long",LOGLEVEL_CONSTRUCT);
     value = new ::cl_I(i);
     calchash();
-    setflag(status_flags::evaluated|
+    setflag(status_flags::evaluated |
+            status_flags::expanded |
             status_flags::hash_calculated);
 }
 
@@ -186,7 +189,8 @@ numeric::numeric(unsigned long i) : basic(TINFO_numeric)
     debugmsg("numeric constructor from ulong",LOGLEVEL_CONSTRUCT);
     value = new ::cl_I(i);
     calchash();
-    setflag(status_flags::evaluated|
+    setflag(status_flags::evaluated |
+            status_flags::expanded |
             status_flags::hash_calculated);
 }
 
@@ -197,11 +201,12 @@ numeric::numeric(long numer, long denom) : basic(TINFO_numeric)
 {
     debugmsg("numeric constructor from long/long",LOGLEVEL_CONSTRUCT);
     if (!denom)
-        throw (std::overflow_error("division by zero"));
+        throw std::overflow_error("division by zero");
     value = new ::cl_I(numer);
     *value = *value / ::cl_I(denom);
     calchash();
-    setflag(status_flags::evaluated|
+    setflag(status_flags::evaluated |
+            status_flags::expanded |
             status_flags::hash_calculated);
 }
 
@@ -215,7 +220,8 @@ numeric::numeric(double d) : basic(TINFO_numeric)
     value = new cl_N;
     *value = cl_float(d, cl_default_float_format);
     calchash();
-    setflag(status_flags::evaluated|
+    setflag(status_flags::evaluated |
+            status_flags::expanded |
             status_flags::hash_calculated);
 }
 
@@ -286,7 +292,8 @@ numeric::numeric(const cl_N & z) : basic(TINFO_numeric)
     debugmsg("numeric constructor from cl_N", LOGLEVEL_CONSTRUCT);
     value = new ::cl_N(z);
     calchash();
-    setflag(status_flags::evaluated|
+    setflag(status_flags::evaluated |
+            status_flags::expanded |
             status_flags::hash_calculated);
 }
 
@@ -329,7 +336,8 @@ numeric::numeric(const archive_node &n, const lst &sym_lst) : inherited(n, sym_l
         }
     }
     calchash();
-    setflag(status_flags::evaluated|
+    setflag(status_flags::evaluated |
+            status_flags::expanded |
             status_flags::hash_calculated);
 }
 
@@ -716,7 +724,7 @@ numeric numeric::mul(const numeric & other) const
 numeric numeric::div(const numeric & other) const
 {
     if (::zerop(*other.value))
-        throw (std::overflow_error("division by zero"));
+        throw std::overflow_error("numeric::div(): division by zero");
     return numeric((*value)/(*other.value));
 }
 
@@ -727,11 +735,11 @@ numeric numeric::power(const numeric & other) const
         return *this;
     if (::zerop(*value)) {
         if (::zerop(*other.value))
-            throw (std::domain_error("numeric::eval(): pow(0,0) is undefined"));
+            throw std::domain_error("numeric::eval(): pow(0,0) is undefined");
         else if (::zerop(::realpart(*other.value)))
-            throw (std::domain_error("numeric::eval(): pow(0,I) is undefined"));
+            throw std::domain_error("numeric::eval(): pow(0,I) is undefined");
         else if (::minusp(::realpart(*other.value)))
-            throw (std::overflow_error("numeric::eval(): division by zero"));
+            throw std::overflow_error("numeric::eval(): division by zero");
         else
             return _num0();
     }
@@ -741,6 +749,8 @@ numeric numeric::power(const numeric & other) const
 /** Inverse of a number. */
 numeric numeric::inverse(void) const
 {
+    if (::zerop(*value))
+        throw std::overflow_error("numeric::inverse(): division by zero");
     return numeric(::recip(*value));  // -> CLN
 }
 
@@ -771,7 +781,7 @@ const numeric & numeric::mul_dyn(const numeric & other) const
 const numeric & numeric::div_dyn(const numeric & other) const
 {
     if (::zerop(*other.value))
-        throw (std::overflow_error("division by zero"));
+        throw std::overflow_error("division by zero");
     return static_cast<const numeric &>((new numeric((*value)/(*other.value)))->
                                         setflag(status_flags::dynallocated));
 }
@@ -783,11 +793,11 @@ const numeric & numeric::power_dyn(const numeric & other) const
         return *this;
     if (::zerop(*value)) {
         if (::zerop(*other.value))
-            throw (std::domain_error("numeric::eval(): pow(0,0) is undefined"));
+            throw std::domain_error("numeric::eval(): pow(0,0) is undefined");
         else if (::zerop(::realpart(*other.value)))
-            throw (std::domain_error("numeric::eval(): pow(0,I) is undefined"));
+            throw std::domain_error("numeric::eval(): pow(0,I) is undefined");
         else if (::minusp(::realpart(*other.value)))
-            throw (std::overflow_error("numeric::eval(): division by zero"));
+            throw std::overflow_error("numeric::eval(): division by zero");
         else
             return _num0();
     }
@@ -993,7 +1003,7 @@ bool numeric::operator<(const numeric & other) const
 {
     if (this->is_real() && other.is_real())
         return (The(::cl_R)(*value) < The(::cl_R)(*other.value));  // -> CLN
-    throw (std::invalid_argument("numeric::operator<(): complex inequality"));
+    throw std::invalid_argument("numeric::operator<(): complex inequality");
     return false;  // make compiler shut up
 }
 
@@ -1004,7 +1014,7 @@ bool numeric::operator<=(const numeric & other) const
 {
     if (this->is_real() && other.is_real())
         return (The(::cl_R)(*value) <= The(::cl_R)(*other.value));  // -> CLN
-    throw (std::invalid_argument("numeric::operator<=(): complex inequality"));
+    throw std::invalid_argument("numeric::operator<=(): complex inequality");
     return false;  // make compiler shut up
 }
 
@@ -1015,7 +1025,7 @@ bool numeric::operator>(const numeric & other) const
 {
     if (this->is_real() && other.is_real())
         return (The(::cl_R)(*value) > The(::cl_R)(*other.value));  // -> CLN
-    throw (std::invalid_argument("numeric::operator>(): complex inequality"));
+    throw std::invalid_argument("numeric::operator>(): complex inequality");
     return false;  // make compiler shut up
 }
 
@@ -1026,7 +1036,7 @@ bool numeric::operator>=(const numeric & other) const
 {
     if (this->is_real() && other.is_real())
         return (The(::cl_R)(*value) >= The(::cl_R)(*other.value));  // -> CLN
-    throw (std::invalid_argument("numeric::operator>=(): complex inequality"));
+    throw std::invalid_argument("numeric::operator>=(): complex inequality");
     return false;  // make compiler shut up
 }
 
@@ -1225,11 +1235,11 @@ const numeric exp(const numeric & x)
  *
  *  @param z complex number
  *  @return  arbitrary precision numerical log(x).
- *  @exception overflow_error (logarithmic singularity) */
+ *  @exception pole_error("log(): logarithmic pole",0) */
 const numeric log(const numeric & z)
 {
     if (z.is_zero())
-        throw (std::overflow_error("log(): logarithmic singularity"));
+        throw pole_error("log(): logarithmic pole",0);
     return ::log(*z.value);  // -> CLN
 }
 
@@ -1283,13 +1293,13 @@ const numeric acos(const numeric & x)
  *
  *  @param z complex number
  *  @return atan(z)
- *  @exception overflow_error (logarithmic singularity) */
+ *  @exception pole_error("atan(): logarithmic pole",0) */
 const numeric atan(const numeric & x)
 {
     if (!x.is_real() &&
         x.real().is_zero() &&
-        !abs(x.imag()).is_equal(_num1()))
-        throw (std::overflow_error("atan(): logarithmic singularity"));
+        abs(x.imag()).is_equal(_num1()))
+        throw pole_error("atan(): logarithmic pole",0);
     return ::atan(*x.value);  // -> CLN
 }
 
@@ -1304,7 +1314,7 @@ const numeric atan(const numeric & y, const numeric & x)
     if (x.is_real() && y.is_real())
         return ::atan(::realpart(*x.value), ::realpart(*y.value));  // -> CLN
     else
-        throw (std::invalid_argument("numeric::atan(): complex argument"));        
+        throw std::invalid_argument("atan(): complex argument");        
 }
 
 
@@ -1530,7 +1540,7 @@ const numeric psi(const numeric & n, const numeric & x)
 const numeric factorial(const numeric & n)
 {
     if (!n.is_nonneg_integer())
-        throw (std::range_error("numeric::factorial(): argument must be integer >= 0"));
+        throw std::range_error("numeric::factorial(): argument must be integer >= 0");
     return numeric(::factorial(n.to_int()));  // -> CLN
 }
 
@@ -1547,7 +1557,7 @@ const numeric doublefactorial(const numeric & n)
         return _num1();
     }
     if (!n.is_nonneg_integer()) {
-        throw (std::range_error("numeric::doublefactorial(): argument must be integer >= -1"));
+        throw std::range_error("numeric::doublefactorial(): argument must be integer >= -1");
     }
     return numeric(::doublefactorial(n.to_int()));  // -> CLN
 }
@@ -1571,7 +1581,7 @@ const numeric binomial(const numeric & n, const numeric & k)
     }
     
     // should really be gamma(n+1)/gamma(r+1)/gamma(n-r+1) or a suitable limit
-    throw (std::range_error("numeric::binomial(): don´t know how to evaluate that."));
+    throw std::range_error("numeric::binomial(): don´t know how to evaluate that.");
 }
 
 
@@ -1583,7 +1593,7 @@ const numeric binomial(const numeric & n, const numeric & k)
 const numeric bernoulli(const numeric & nn)
 {
     if (!nn.is_integer() || nn.is_negative())
-        throw (std::range_error("numeric::bernoulli(): argument must be integer >= 0"));
+        throw std::range_error("numeric::bernoulli(): argument must be integer >= 0");
     
     // Method:
     //
@@ -1660,7 +1670,7 @@ const numeric bernoulli(const numeric & nn)
 const numeric fibonacci(const numeric & n)
 {
     if (!n.is_integer())
-        throw (std::range_error("numeric::fibonacci(): argument must be integer"));
+        throw std::range_error("numeric::fibonacci(): argument must be integer");
     // Method:
     //
     // This is based on an implementation that can be found in CLN's example