X-Git-Url: https://git.ucc.asn.au/?p=ipdf%2Fcode.git;a=blobdiff_plain;f=src%2Fparanoidnumber.h;h=6ad24f254ae2246fb1fdc4011b6230f9668d9885;hp=b15292275c81a23e9f3caa8bc5d39f1e5023d675;hb=1d179b93f6a1b2a4fe3823c26fba862c24bc5d6e;hpb=03cc1b0a0d0705e0b1d92e13fdb18608c7a00272 diff --git a/src/paranoidnumber.h b/src/paranoidnumber.h index b152922..6ad24f2 100644 --- a/src/paranoidnumber.h +++ b/src/paranoidnumber.h @@ -16,12 +16,16 @@ // but let's not do that... -#define PARANOID_CACHE_RESULTS +//#define PARANOID_CACHE_RESULTS //#define PARANOID_USE_ARENA #define PARANOID_SIZE_LIMIT 0 +// Define to compare all ops against double ops and check within epsilon +#define PARANOID_COMPARE_EPSILON 1e-6 +#define CompareForSanity(...) this->ParanoidNumber::CompareForSanityEx(__func__, __FILE__, __LINE__, __VA_ARGS__) + namespace IPDF { typedef enum {ADD, SUBTRACT, MULTIPLY, DIVIDE, NOP} Optype; @@ -184,6 +188,7 @@ namespace IPDF ParanoidNumber operator+(const ParanoidNumber & a) const { ParanoidNumber result(*this); + a.SanityCheck(); result += a; return result; } @@ -197,6 +202,10 @@ namespace IPDF { ParanoidNumber result(*this); result *= a; + if (!result.SanityCheck()) + { + Fatal("Blargh"); + } return result; } ParanoidNumber operator/(const ParanoidNumber & a) const @@ -208,7 +217,15 @@ namespace IPDF std::string Str() const; - + inline void CompareForSanityEx(const char * func, const char * file, int line, const digit_t & compare, const digit_t & arg, const digit_t & eps = PARANOID_COMPARE_EPSILON) + { + if (fabs(Digit() - compare) > eps) + { + Error("Called via %s(%lf) (%s:%d)", func, arg, file, line); + Error("Failed: %s", Str().c_str()); + Fatal("This: %.30lf vs Expected: %.30lf", Digit(), compare); + } + } std::string PStr() const;