X-Git-Url: https://git.ucc.asn.au/?p=ipdf%2Fcode.git;a=blobdiff_plain;f=src%2Ftests%2Fparanoidtester.cpp;fp=src%2Ftests%2Fparanoidtester.cpp;h=bf1dc0bf507729003d7e70ba585b5e8707a559f6;hp=0000000000000000000000000000000000000000;hb=dfba002efc3b5f126ddb69e63b9a7dafdd9eacda;hpb=6472d20ee58d2ecc0aee8bc1a12a071b2afc8a27 diff --git a/src/tests/paranoidtester.cpp b/src/tests/paranoidtester.cpp new file mode 100644 index 0000000..bf1dc0b --- /dev/null +++ b/src/tests/paranoidtester.cpp @@ -0,0 +1,99 @@ +#include "main.h" +#include "real.h" +#include +#include +#include +#include +#include +#include +#include +#include "paranoidnumber.h" + +using namespace std; +using namespace IPDF; + +string RandomNumberAsString(int digits = 6) +{ + string result(""); + int dp = 1+(rand() % 3); + for (int i = 0; i < digits; ++i) + { + if (i == dp) + { + result += "."; + continue; + } + result += ('0'+rand() % 10); + } + return result; +} + +#define TEST_CASES 10000 + +int main(int argc, char ** argv) +{ + + string number(RandomNumberAsString()); + ParanoidNumber a(number); + float fa = strtof(number.c_str(), NULL); + double da = strtod(number.c_str(), NULL); + long double lda = strtold(number.c_str(), NULL); + + if (fabs(a.ToDouble() - da) > 1e-6) + { + Error("double %lf, pn %lf {%s}", da, a.ToDouble(), a.Str().c_str()); + Fatal("Didn't construct correctly off %s", number.c_str()); + } + + char opch[] = {'+','-','*','/'}; + + for (int i = 0; i < TEST_CASES; ++i) + { + number = RandomNumberAsString(); + ParanoidNumber b(number); + float fb = strtof(number.c_str(), NULL); + double db = strtod(number.c_str(), NULL); + long double ldb = strtold(number.c_str(), NULL); + int op = (rand() % 4); + ParanoidNumber olda(a); + double oldda(da); + switch (op) + { + case 0: + a += b; + fa += fb; + da += db; + lda += ldb; + break; + case 1: + a -= b; + fa -= fb; + da -= db; + lda -= ldb; + break; + case 2: + a *= b; + fa *= fb; + da *= db; + lda *= ldb; + break; + case 3: + a /= b; + fa /= fb; + da /= db; + lda /= ldb; + break; + } + if (fabs(a.ToDouble() - da) > 1.0 ) + { + 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); + } + } + 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); +}