Careful, you may have to shade your eyes
[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-1)
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         
26         unsigned failures = 0;
27         for (unsigned i = 0; i < TEST_CASES; ++i)
28         {
29                 //Debug("Test %u of %u", i, TEST_CASES);
30                 double da = (double)(rand() + 1) / (double)(rand() + 1);
31                 double db = (double)(rand() + 1) / (double)(rand() + 1);
32                 
33                 if (rand() % 2 == 0)
34                         da = -da;
35                 if (rand() % 2 == 0)
36                         db = -db;
37                 
38                 Real a(da);
39                 Real b(db);
40                 Real aa(a);
41                 Real bb(b);
42                 unsigned old_failures = failures;
43                 if (NotEqual(Double(a), Double(aa)))
44                 {
45                         failures++;
46                         Warn("a != Real(a); %f vs %f", Double(a), Double(aa));
47                 }
48                 if (NotEqual(Double(b), Double(bb)))
49                 {
50                         failures++;
51                         Warn("b != Real(b); %f vs %f", Double(b), Double(bb));
52                 }
53                 
54                 if (NotEqual(Double(a), da))
55                 {
56                         failures++;
57                         Warn("a != da; %f vs %f", Double(a), da);
58                 }
59                 if (NotEqual(Double(b), db))
60                 {
61                         failures++;                     
62                         Warn("b != db; %f vs %f", Double(b), db);
63                 }
64                 if (NotEqual(Double(a+b), da+db))
65                 {
66                         failures++;                     
67                         Warn("a + b = %f should be %f", Double(a+b), da+db);
68                 }
69                 if (NotEqual(Double(a-b), da-db))
70                 {
71                         failures++;                     
72                         Warn("a - b = %f should be %f", Double(a-b), da-db);
73                 }
74                 if (NotEqual(Double(a*b), da*db))
75                 {
76                         failures++;                     
77                         Warn("a * b = %f should be %f", Double(a*b), da*db);
78                 }
79                 if (NotEqual(Double(a/b), da/db))
80                 {
81                         failures++;                     
82                         Warn("a / b = %f should be %f", Double(a/b), da/db);
83                 }               
84
85                 if (NotEqual(Double(a), da))
86                 {
87                         failures++;                     
88                         Warn("a has changed after +-*/ from %f to %f", da, Double(a));
89                 }
90                 if (NotEqual(Double(b), db))
91                 {
92                         failures++;                     
93                         Warn("b has changed after +-*/ from %f to %f", db, Double(b));
94                 }
95                 Real abeforeop(a);
96                 if (NotEqual(Double(a+=b), da+=db))
97                 {
98                         failures++;                     
99                         Warn("a += b = %f should be %f, a before op was %f", Double(a), da, Double(abeforeop));
100                 }
101                 abeforeop = a;
102                 if (NotEqual(Double(a-=b), da-=db))
103                 {
104                         failures++;                     
105                         Warn("a -= b = %f should be %f, a before op was %f", Double(a), da, Double(abeforeop));
106                 }
107                 abeforeop = a;
108                 if (NotEqual(Double(a*=b), da*=db))
109                 {
110                         failures++;                     
111                         Warn("a *= b = %f should be %f, a before op was %f", Double(a), da, Double(abeforeop));
112                 }
113                 abeforeop = a;
114                 if (NotEqual(Double(a/=b), da/=db))
115                 {
116                         failures++;
117                         Warn("a /= b = %f should be %f, a before op was %f", Double(a), da, Double(abeforeop));
118                 }               
119                 
120                 if (failures > old_failures)
121                 {
122                         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));
123                         #if REAL == REAL_RATIONAL || REAL == REAL_RATIONAL_ARBINT
124                                 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());
125                         #endif
126                 }
127         }
128         Debug("Completed %u test cases with total of %u operations, %u failures", TEST_CASES, 12*TEST_CASES, failures);
129         Debug("Total accumulated difference between Real and Double operations was %f", g_totalerror);
130
131 }

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