This did not happen for the binary relational operators between numerics.
Now the behaviour is more consistent (throwing exceptions when the difference
becomes complex).
* Some regression tests were actually wrong in the light of this bug. :-(
argument = numeric(20.0*rand()/(RAND_MAX+1.0)-10.0)
+ numeric(20.0*rand()/(RAND_MAX+1.0)-10.0)*I;
if (abs(Li2(pow(argument,2))-2*Li2(argument)-2*Li2(-argument)) > epsilon) {
- cout << "Li2(z) at z==" << argument
+ clog << "Li2(z) at z==" << argument
<< " failed to satisfy Li2(z^2)==2*(Li2(z)+Li2(-z))" << endl;
errorflag = true;
}
int i_num, i_den;
// Check non-nested radicals (n/d)^(m/n) in ex wrapper class:
- for (int i=0; i<200; ++i) { // FIXME: run to ~200
+ for (int i=0; i<200; ++i) {
for (int j=2; j<13; ++j) {
// construct an exponent 1/j...
numeric nm(1,j);
<< radical << endl;
errorflag = true;
}
- numeric ratio = ex_to<numeric>(evalf(radical))/floating;
+ numeric ratio = ex_to<numeric>(abs(evalf(radical)))/floating;
if (ratio>1.0001 && ratio<0.9999) {
clog << "(" << num << "/" << den << ")^(" << nm
<< ") erroneously evaluated to " << radical;
// default ctor, dtor, copy ctor assignment operator and helpers
//////////
-power::power() : basic(TINFO_power)
+power::power() : inherited(TINFO_power)
{
debugmsg("power default ctor",LOGLEVEL_CONSTRUCT);
}
// other ctors
//////////
-power::power(const ex & lh, const ex & rh) : basic(TINFO_power), basis(lh), exponent(rh)
+power::power(const ex & lh, const ex & rh) : inherited(TINFO_power), basis(lh), exponent(rh)
{
debugmsg("power ctor from ex,ex",LOGLEVEL_CONSTRUCT);
}
/** Ctor from an ex and a bare numeric. This is somewhat more efficient than
* the normal ctor from two ex whenever it can be used. */
-power::power(const ex & lh, const numeric & rh) : basic(TINFO_power), basis(lh), exponent(rh)
+power::power(const ex & lh, const numeric & rh) : inherited(TINFO_power), basis(lh), exponent(rh)
{
debugmsg("power ctor from ex,numeric",LOGLEVEL_CONSTRUCT);
}
// non-virtual functions in this class
//////////
+/** Cast the relational into a boolean, mainly for evaluation within an
+ * if-statement. Note that (a<b) == false does not imply (a>=b) == true in
+ * the general symbolic case. A false result means the comparison is either
+ * false or undecidable (except of course for !=, where true means either
+ * unequal or undecidable). */
relational::operator bool() const
{
- // please note that (a<b) == false does not imply (a>=b) == true
- // a false result means the comparison is either false or undecidable
- // (except for !=, where true means unequal or undecidable)
- ex df = lh-rh;
+ const ex df = lh-rh;
if (!is_ex_exactly_of_type(df,numeric))
// cannot decide on non-numerical results
return o==not_equal ? true : false;
- int cmpval = ex_to<numeric>(df).compare(_num0());
switch (o) {
case equal:
- return cmpval==0;
+ return ex_to<numeric>(df).is_zero();
case not_equal:
- return cmpval!=0;
+ return !ex_to<numeric>(df).is_zero();
case less:
- return cmpval<0;
+ return ex_to<numeric>(df)<_num0();
case less_or_equal:
- return cmpval<=0;
+ return ex_to<numeric>(df)<=_num0();
case greater:
- return cmpval>0;
+ return ex_to<numeric>(df)>_num0();
case greater_or_equal:
- return cmpval>=0;
+ return ex_to<numeric>(df)>=_num0();
default:
throw(std::logic_error("invalid relational operator"));
}