2 * Test mathematical operations on the Real type and consistency with double
11 #define TEST_CASES 1000
13 static double g_totalerror = 0;
15 bool NotEqual(double a, double b, double threshold=1e-4)
17 double error = fabs(a-b);
18 g_totalerror += error;
19 return (error > threshold);
22 int main(int argc, char ** argv)
27 unsigned failures = 0;
29 double dacumulate = 0;
30 for (unsigned i = 0; i < TEST_CASES; ++i)
32 //Debug("Test %u of %u", i, TEST_CASES);
33 double da = (double)(rand() + 1) / (double)(rand() + 1);
34 double db = (double)(rand() + 1) / (double)(rand() + 1);
45 unsigned old_failures = failures;
46 if (NotEqual(Double(a), Double(aa)))
49 Warn("a != Real(a); %f vs %f", Double(a), Double(aa));
51 if (NotEqual(Double(b), Double(bb)))
54 Warn("b != Real(b); %f vs %f", Double(b), Double(bb));
57 if (NotEqual(Double(a), da))
60 Warn("a != da; %f vs %f", Double(a), da);
62 if (NotEqual(Double(b), db))
65 Warn("b != db; %f vs %f", Double(b), db);
67 if (NotEqual(Double(a+b), da+db))
70 Warn("a + b = %f should be %f", Double(a+b), da+db);
72 if (NotEqual(Double(a-b), da-db))
75 Warn("a - b = %f should be %f", Double(a-b), da-db);
77 if (NotEqual(Double(a*b), da*db))
80 Warn("a * b = %f should be %f", Double(a*b), da*db);
82 if (NotEqual(Double(a/b), da/db))
85 Warn("a / b = %f should be %f", Double(a/b), da/db);
88 if (NotEqual(Double(a), da))
91 Warn("a has changed after +-*/ from %f to %f", da, Double(a));
93 if (NotEqual(Double(b), db))
96 Warn("b has changed after +-*/ from %f to %f", db, Double(b));
99 if (NotEqual(Double(a+=b), da+=db))
102 Warn("a += b = %f should be %f, a before op was %f", Double(a), da, Double(abeforeop));
105 if (NotEqual(Double(a-=b), da-=db))
108 Warn("a -= b = %f should be %f, a before op was %f", Double(a), da, Double(abeforeop));
111 if (NotEqual(Double(a*=b), da*=db))
114 Warn("a *= b = %f should be %f, a before op was %f", Double(a), da, Double(abeforeop));
117 if (NotEqual(Double(a/=b), da/=db))
120 Warn("a /= b = %f should be %f, a before op was %f", Double(a), da, Double(abeforeop));
122 if (NotEqual(Double(a*0.0 + 1.0), da*0.0 + 1.0))
125 Warn("a * 0 = %f should be %f, a before op was %f", Double(a), da, Double(abeforeop));
128 if (NotEqual(Double(a=b), da=db))
131 Warn("a = b = %f should be %f, a before op was %f", Double(a), da, Double(abeforeop));
134 if (NotEqual(Double(-a), -da))
137 Warn("-a = %f should be %f, a before op was %f", Double(-a), -da, Double(abeforeop));
140 if (NotEqual(Double(Sqrt(a)), Sqrt(da)))
143 Warn("Sqrt(a) = %f should be %f, a before op was %f", Double(Sqrt(a)), Sqrt(da), Double(abeforeop));
146 if (NotEqual(Double(a), da))
149 Warn("a = %f, should be %f, a before ops was %f", Double(a), da, Double(abeforeop));
171 if (NotEqual(Double(acumulate), dacumulate))
173 Warn("Accumulated result %.30lf vs %.30lf is wrong", Double(acumulate), dacumulate);
177 if (failures > old_failures)
179 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));
180 #if REAL == REAL_RATIONAL || REAL == REAL_RATIONAL_ARBINT
181 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());
186 Debug("Completed %u test cases with total of %u operations, %u failures", TEST_CASES, 18*TEST_CASES, failures);
187 Debug("Total accumulated difference between Real and Double operations was %f", g_totalerror);
188 Debug("Real: %.40lf", Double(acumulate));
189 Debug("Doub: %.40lf", dacumulate);
190 Debug("Diff: %.40lf", Double(acumulate) - dacumulate);