Paranoia is setting in
[ipdf/code.git] / src / tests / paranoidtester.cpp
index bf1dc0b..98c056d 100644 (file)
@@ -8,14 +8,16 @@
 #include <cfloat>
 #include <fenv.h>
 #include "paranoidnumber.h"
+#include "progressbar.h"
 
 using namespace std;
 using namespace IPDF;
 
-string RandomNumberAsString(int digits = 6)
+string RandomNumberAsString(int max_digits = 12)
 {
        string result("");
-       int dp = 1+(rand() % 3);
+       int digits = 1+(rand() % max_digits);
+       int dp = (rand() % digits)+1;
        for (int i = 0; i < digits; ++i)
        {
                if (i == dp)
@@ -28,15 +30,25 @@ string RandomNumberAsString(int digits = 6)
        return result;
 }
 
-#define TEST_CASES 10000
+bool CloseEnough(double d, ParanoidNumber & p)
+{
+       double pd = p.ToDouble();
+               
+       if (d == 0)
+               return fabs(pd) <= 1e-6;
+       return fabs((fabs(pd - d) / d)) <= 1e-6;
+}
+
+#define TEST_CASES 1000
 
 int main(int argc, char ** argv)
 {
-
+       srand(time(NULL));
        string number(RandomNumberAsString());
        ParanoidNumber a(number);
        float fa = strtof(number.c_str(), NULL);
        double da = strtod(number.c_str(), NULL);
+       double diff = 0;
        long double lda = strtold(number.c_str(), NULL);
        
        if (fabs(a.ToDouble() - da) > 1e-6)
@@ -46,15 +58,27 @@ int main(int argc, char ** argv)
        }
        
        char opch[] = {'+','-','*','/'};
-       
+       int opcount[] = {0,0,0,0};
        for (int i = 0; i < TEST_CASES; ++i)
        {
+               ProgressBar(i, TEST_CASES); fprintf(stderr, "%.30lf (%d)+ (%d)- (%d)* (%d)/ [Paranoia %ld]",diff, opcount[0],opcount[1],opcount[2],opcount[3], ParanoidNumber::Paranoia());
                number = RandomNumberAsString();
                ParanoidNumber b(number);
                float fb = strtof(number.c_str(), NULL);
                double db = strtod(number.c_str(), NULL);
+               if (db == 0)
+               {
+                       --i;
+                       continue;
+               }
                long double ldb = strtold(number.c_str(), NULL);
-               int op = (rand() % 4);
+               int op = rand() % 4;//= 2*(rand() % 2);
+               while (op == 1)
+                       op = rand() % 4;
+               //if (rand() % 2 == 0)
+                       //op = 2+(rand() % 2);
+                       
+               opcount[op]++;
                ParanoidNumber olda(a);
                double oldda(da);
                switch (op)
@@ -84,16 +108,23 @@ int main(int argc, char ** argv)
                                lda /= ldb;
                                break;
                }
-               if (fabs(a.ToDouble() - da) > 1.0 )
+               diff = 100.0*(fabs(a.ToDouble() - da) / da);
+               if (!CloseEnough(da, a))
                {
                        Error("Op %i: ParanoidNumber probably doesn't work", i);
                        Error("Operation: %lf %c %lf", oldda, opch[op], db);
                        Error("As PN: %lf %c %lf", olda.ToDouble(), opch[op], b.ToDouble());
-                       Fatal("%lf, expected aboout %lf", a.ToDouble(), da);
+                       Error("PN String: %s", a.Str().c_str());
+                       Error("Diff is %.40lf", diff);
+                       Fatal("%.40lf, expected aboout %.40lf", a.ToDouble(), da);
+                       
+                       
                }
+               
        }
        printf("ParanoidNumber: {%s} = %.40lf\n", a.Str().c_str(), a.ToDouble());
        printf("float: %.40f\n", fa);
        printf("double: %.40lf\n", da);
        printf("long double: %.40Lf\n", lda);
+       printf("diff %.40lf\n", diff);
 }

UCC git Repository :: git.ucc.asn.au