[bugfix] Make sure add::eval() collects all numeric terms *correctly*.
authorRichard Kreckel <kreckel@ginac.de>
Thu, 17 Dec 2015 21:30:13 +0000 (22:30 +0100)
committerRichard Kreckel <kreckel@ginac.de>
Thu, 17 Dec 2015 21:30:13 +0000 (22:30 +0100)
This fixes a bug introduced with in 2010 with 89d5356b.

check/exam_paranoia.cpp
ginac/add.cpp

index 711c64a..81dda85 100644 (file)
@@ -468,16 +468,26 @@ static unsigned exam_paranoia17()
 }
 
 // Bug in add::eval() could result in numeric terms not being collected into
-// the overall coefficient. Fixed on Sep 22, 2010
+// the overall coefficient. Fixed first on Sep 22, 2010 and again on Dec 17 2015
 static unsigned exam_paranoia18()
 {
+       unsigned result = 0;
+
        ex sqrt2 = sqrt(ex(2));
-       ex e = 1+2*(sqrt2+1)*(sqrt2-1);
-       if ( e.real_part() != 3 ) {
+       ex e = 1 + 2*(sqrt2+1)*(sqrt2-1);
+       if (e.real_part() != 3) {
                clog << "real_part(1+2*(sqrt(2)+1)*(sqrt(2)-1)) failed to evaluate to 3\n";
-               return 1;
+               ++result;
        }
-       return 0;
+
+       ex sqrt3 = sqrt(ex(3));
+       ex f = 2 + 2*(sqrt2+1)*(sqrt2-1) - 2*(sqrt3+1)*(sqrt3-1);
+       if (f.real_part() != 0) {
+               clog << "real_part(2+2*(sqrt(2)+1)*(sqrt(2)-1)-3*(sqrt(3)+1)*(sqrt(3)-1)) failed to evaluate to 0\n";
+               ++result;
+       }
+
+       return result;
 }
 
 // Bug in mul::conjugate when factors are evaluated at branch cuts, reported as
index ccd4924..1a19d86 100644 (file)
@@ -388,11 +388,11 @@ ex add::eval(int level) const
        if (terms_to_collect) {
                std::auto_ptr<epvector> s(new epvector);
                s->reserve(seq_size - terms_to_collect);
-               numeric oc = *_num1_p;
+               numeric oc = *_num0_p;
                j = seq.begin();
                while (j != last) {
                        if (unlikely(is_a<numeric>(j->rest)))
-                               oc = oc.mul(ex_to<numeric>(j->rest)).mul(ex_to<numeric>(j->coeff));
+                               oc = oc.add(ex_to<numeric>(j->rest).mul(ex_to<numeric>(j->coeff)));
                        else
                                s->push_back(*j);
                        ++j;