dd45aa8dbd58a36f27bdaae9ff6bdc100144808b
[ipdf/code.git] / src / tests / realops.cpp
1 /**
2  * Test mathematical operations on the Real type and consistency with double
3  */
4
5 #include "main.h"
6 #include "real.h"
7
8 using namespace std;
9 using namespace IPDF;
10
11 #define TEST_CASES 1000
12
13 static double g_totalerror = 0;
14
15 bool NotEqual(double a, double b, double threshold=1e-4)
16 {
17         double error = fabs(a-b);
18         g_totalerror += error;
19         return (error > threshold);
20 }
21
22 int main(int argc, char ** argv)
23 {
24         srand(time(NULL));
25         DebugRealInfo();
26         
27         unsigned failures = 0;
28         for (unsigned i = 0; i < TEST_CASES; ++i)
29         {
30                 //Debug("Test %u of %u", i, TEST_CASES);
31                 double da = (double)(rand() + 1) / (double)(rand() + 1);
32                 double db = (double)(rand() + 1) / (double)(rand() + 1);
33                 
34                 if (rand() % 2 == 0)
35                         da = -da;
36                 if (rand() % 2 == 0)
37                         db = -db;
38                 
39                 Real a(da);
40                 Real b(db);
41                 Real aa(a);
42                 Real bb(b);
43                 unsigned old_failures = failures;
44                 if (NotEqual(Double(a), Double(aa)))
45                 {
46                         failures++;
47                         Warn("a != Real(a); %f vs %f", Double(a), Double(aa));
48                 }
49                 if (NotEqual(Double(b), Double(bb)))
50                 {
51                         failures++;
52                         Warn("b != Real(b); %f vs %f", Double(b), Double(bb));
53                 }
54                 
55                 if (NotEqual(Double(a), da))
56                 {
57                         failures++;
58                         Warn("a != da; %f vs %f", Double(a), da);
59                 }
60                 if (NotEqual(Double(b), db))
61                 {
62                         failures++;                     
63                         Warn("b != db; %f vs %f", Double(b), db);
64                 }
65                 if (NotEqual(Double(a+b), da+db))
66                 {
67                         failures++;                     
68                         Warn("a + b = %f should be %f", Double(a+b), da+db);
69                 }
70                 if (NotEqual(Double(a-b), da-db))
71                 {
72                         failures++;                     
73                         Warn("a - b = %f should be %f", Double(a-b), da-db);
74                 }
75                 if (NotEqual(Double(a*b), da*db))
76                 {
77                         failures++;                     
78                         Warn("a * b = %f should be %f", Double(a*b), da*db);
79                 }
80                 if (NotEqual(Double(a/b), da/db))
81                 {
82                         failures++;                     
83                         Warn("a / b = %f should be %f", Double(a/b), da/db);
84                 }               
85
86                 if (NotEqual(Double(a), da))
87                 {
88                         failures++;                     
89                         Warn("a has changed after +-*/ from %f to %f", da, Double(a));
90                 }
91                 if (NotEqual(Double(b), db))
92                 {
93                         failures++;                     
94                         Warn("b has changed after +-*/ from %f to %f", db, Double(b));
95                 }
96                 Real abeforeop(a);
97                 if (NotEqual(Double(a+=b), da+=db))
98                 {
99                         failures++;                     
100                         Warn("a += b = %f should be %f, a before op was %f", Double(a), da, Double(abeforeop));
101                 }
102                 abeforeop = a;
103                 if (NotEqual(Double(a-=b), da-=db))
104                 {
105                         failures++;                     
106                         Warn("a -= b = %f should be %f, a before op was %f", Double(a), da, Double(abeforeop));
107                 }
108                 abeforeop = a;
109                 if (NotEqual(Double(a*=b), da*=db))
110                 {
111                         failures++;                     
112                         Warn("a *= b = %f should be %f, a before op was %f", Double(a), da, Double(abeforeop));
113                 }
114                 abeforeop = a;
115                 if (NotEqual(Double(a/=b), da/=db))
116                 {
117                         failures++;
118                         Warn("a /= b = %f should be %f, a before op was %f", Double(a), da, Double(abeforeop));
119                 }
120                 if (NotEqual(Double(a*0.0 + 1.0), da*0.0 + 1.0))
121                 {
122                         failures++;
123                         Warn("a * 0 = %f should be %f, a before op was %f", Double(a), da, Double(abeforeop));
124                 }               
125
126                 if (NotEqual(Double(a=b), da=db))
127                 {
128                         failures++;
129                         Warn("a = b = %f should be %f, a before op was %f", Double(a), da, Double(abeforeop));
130                 }
131                 
132                 if (failures > old_failures)
133                 {
134                         Error("%u failures on case %u da = %f, db = %f, a = %f, b = %f, aa = %f, bb = %f", failures-old_failures, i, da, db, Double(a), Double(b), Double(aa), Double(bb));
135                         #if REAL == REAL_RATIONAL || REAL == REAL_RATIONAL_ARBINT
136                                 Debug("\tStrings are a = %s, b = %s, aa = %s, bb = %s", a.Str().c_str(), b.Str().c_str(), aa.Str().c_str(), bb.Str().c_str());
137                         #endif
138                 }
139         }
140         Debug("Completed %u test cases with total of %u operations, %u failures", TEST_CASES, 12*TEST_CASES, failures);
141         Debug("Total accumulated difference between Real and Double operations was %f", g_totalerror);
142
143 }

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