Add MPFRC++ mpreal type
[ipdf/code.git] / src / tests / paranoidtester.cpp
1 #include "main.h"
2 #include "real.h"
3 #include <cmath>
4 #include <cassert>
5 #include <list>
6 #include <bitset>
7 #include <iostream>
8 #include <cfloat>
9 #include <fenv.h>
10 #include "paranoidnumber.h"
11
12 using namespace std;
13 using namespace IPDF;
14
15 string RandomNumberAsString(int digits = 6)
16 {
17         string result("");
18         int dp = 1+(rand() % 3);
19         for (int i = 0; i < digits; ++i)
20         {
21                 if (i == dp)
22                 {
23                         result += ".";
24                         continue;
25                 }
26                 result += ('0'+rand() % 10);
27         }
28         return result;
29 }
30
31 #define TEST_CASES 10000
32
33 int main(int argc, char ** argv)
34 {
35
36         string number(RandomNumberAsString());
37         ParanoidNumber a(number);
38         float fa = strtof(number.c_str(), NULL);
39         double da = strtod(number.c_str(), NULL);
40         long double lda = strtold(number.c_str(), NULL);
41         
42         if (fabs(a.ToDouble() - da) > 1e-6)
43         {
44                 Error("double %lf, pn %lf {%s}", da, a.ToDouble(), a.Str().c_str());
45                 Fatal("Didn't construct correctly off %s", number.c_str());
46         }
47         
48         char opch[] = {'+','-','*','/'};
49         
50         for (int i = 0; i < TEST_CASES; ++i)
51         {
52                 number = RandomNumberAsString();
53                 ParanoidNumber b(number);
54                 float fb = strtof(number.c_str(), NULL);
55                 double db = strtod(number.c_str(), NULL);
56                 long double ldb = strtold(number.c_str(), NULL);
57                 int op = (rand() % 4);
58                 ParanoidNumber olda(a);
59                 double oldda(da);
60                 switch (op)
61                 {
62                         case 0:
63                                 a += b;
64                                 fa += fb;
65                                 da += db;
66                                 lda += ldb;
67                                 break;
68                         case 1:
69                                 a -= b;
70                                 fa -= fb;
71                                 da -= db;
72                                 lda -= ldb;
73                                 break;
74                         case 2:
75                                 a *= b;
76                                 fa *= fb;
77                                 da *= db;
78                                 lda *= ldb;
79                                 break;
80                         case 3:
81                                 a /= b;
82                                 fa /= fb;
83                                 da /= db;
84                                 lda /= ldb;
85                                 break;
86                 }
87                 if (fabs(a.ToDouble() - da) > 1.0 )
88                 {
89                         Error("Op %i: ParanoidNumber probably doesn't work", i);
90                         Error("Operation: %lf %c %lf", oldda, opch[op], db);
91                         Error("As PN: %lf %c %lf", olda.ToDouble(), opch[op], b.ToDouble());
92                         Fatal("%lf, expected aboout %lf", a.ToDouble(), da);
93                 }
94         }
95         printf("ParanoidNumber: {%s} = %.40lf\n", a.Str().c_str(), a.ToDouble());
96         printf("float: %.40f\n", fa);
97         printf("double: %.40lf\n", da);
98         printf("long double: %.40Lf\n", lda);
99 }

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