X-Git-Url: https://git.ucc.asn.au/?p=ipdf%2Fcode.git;a=blobdiff_plain;f=src%2Fparanoidnumber.h;fp=src%2Fparanoidnumber.h;h=b15292275c81a23e9f3caa8bc5d39f1e5023d675;hp=1ffa97b23d3142b8436e6cd7c9b2c93e27ee19be;hb=03cc1b0a0d0705e0b1d92e13fdb18608c7a00272;hpb=ea748154f1bc7dbc81cb52611a52865e63109439;ds=sidebyside diff --git a/src/paranoidnumber.h b/src/paranoidnumber.h index 1ffa97b..b152922 100644 --- a/src/paranoidnumber.h +++ b/src/paranoidnumber.h @@ -12,8 +12,15 @@ #include // it's going to be ok #include -#define PARANOID_DIGIT_T float // we could theoretically replace this with a template +#define PARANOID_DIGIT_T double // we could theoretically replace this with a template // but let's not do that... + + +#define PARANOID_CACHE_RESULTS + +//#define PARANOID_USE_ARENA +#define PARANOID_SIZE_LIMIT 0 + namespace IPDF { @@ -73,23 +80,25 @@ namespace IPDF public: typedef PARANOID_DIGIT_T digit_t; - ParanoidNumber(PARANOID_DIGIT_T value=0) : m_value(value), m_cached_result(value), m_cache_valid(true), m_next() + ParanoidNumber(PARANOID_DIGIT_T value=0) : m_value(value), m_next() { - Construct(); - assert(SanityCheck()); - } - - static ParanoidNumber * SafeConstruct(const ParanoidNumber & cpy) - { - ParanoidNumber * result = new ParanoidNumber(cpy); - assert(result != NULL); - assert(result->SanityCheck()); - return result; + #ifdef PARANOID_SIZE_LIMIT + m_size = 0; + #endif + #ifdef PARANOID_CACHE_RESULTS + m_cached_result = value; + #endif } - ParanoidNumber(const ParanoidNumber & cpy) : m_value(cpy.m_value), m_cached_result(cpy.m_cached_result), m_cache_valid(cpy.m_cache_valid), m_next() + ParanoidNumber(const ParanoidNumber & cpy) : m_value(cpy.m_value), m_next() { - Construct(); + + #ifdef PARANOID_SIZE_LIMIT + m_size = cpy.m_size; + #endif + #ifdef PARANOID_CACHE_RESULTS + m_cached_result = cpy.m_cached_result; + #endif for (int i = 0; i < NOP; ++i) { for (auto next : cpy.m_next[i]) @@ -98,20 +107,14 @@ namespace IPDF m_next[i].push_back(new ParanoidNumber(*next)); // famous last words... } } - assert(SanityCheck()); + //assert(SanityCheck()); } //ParanoidNumber(const char * str); ParanoidNumber(const std::string & str);// : ParanoidNumber(str.c_str()) {} virtual ~ParanoidNumber(); - - inline void Construct() - { - for (int i = 0; i < NOP; ++i) - m_next[i].clear(); - g_count++; - } + bool SanityCheck(std::set & visited) const; bool SanityCheck() const @@ -141,12 +144,20 @@ namespace IPDF bool NoFactors() const {return (m_next[MULTIPLY].size() == 0 && m_next[DIVIDE].size() == 0);} bool NoTerms() const {return (m_next[ADD].size() == 0 && m_next[SUBTRACT].size() == 0);} + ParanoidNumber & operator+=(const ParanoidNumber & a); ParanoidNumber & operator-=(const ParanoidNumber & a); ParanoidNumber & operator*=(const ParanoidNumber & a); ParanoidNumber & operator/=(const ParanoidNumber & a); ParanoidNumber & operator=(const ParanoidNumber & a); + ParanoidNumber & operator+=(const digit_t & a); + ParanoidNumber & operator-=(const digit_t & a); + ParanoidNumber & operator*=(const digit_t & a); + ParanoidNumber & operator/=(const digit_t & a); + ParanoidNumber & operator=(const digit_t & a); + + ParanoidNumber * OperationTerm(ParanoidNumber * b, Optype op, ParanoidNumber ** merge_point = NULL, Optype * mop = NULL); ParanoidNumber * OperationFactor(ParanoidNumber * b, Optype op, ParanoidNumber ** merge_point = NULL, Optype * mop = NULL); ParanoidNumber * TrivialOp(ParanoidNumber * b, Optype op); @@ -197,42 +208,59 @@ namespace IPDF std::string Str() const; - ParanoidNumber * CopyTerms() - { - ParanoidNumber * copy = new ParanoidNumber(*this); - copy->m_value = 0; - copy->Simplify(ADD); - copy->Simplify(SUBTRACT); - return copy; - } - ParanoidNumber * CopyFactors() - { - ParanoidNumber * copy = new ParanoidNumber(*this); - copy->m_value = 1; - copy->Simplify(MULTIPLY); - copy->Simplify(DIVIDE); - return copy; - } - - static int64_t Paranoia() {return g_count;} std::string PStr() const; + + #ifdef PARANOID_USE_ARENA + void * operator new(size_t byes); + void operator delete(void * p); + #endif //PARANOID_USE_ARENA private: - static int64_t g_count; + void Simplify(); void SimplifyTerms(); void SimplifyFactors(); + digit_t m_value; + #ifdef PARANOID_CACHE_RESULTS + digit_t m_cached_result; + #endif + std::vector m_next[4]; + #ifdef PARANOID_SIZE_LIMIT + int64_t m_size; + #endif //PARANOID_SIZE_LIMIT - digit_t m_value; - Optype m_op; + #ifdef PARANOID_USE_ARENA + class Arena + { + public: + Arena(int64_t block_size = 10000000); + ~Arena(); + + void * allocate(size_t bytes); + void deallocate(void * p); + + private: + struct Block + { + void * memory; + int64_t used; + }; + + std::vector m_blocks; + int64_t m_block_size; + + void * m_spare; + + }; - digit_t m_cached_result; - bool m_cache_valid; - std::vector m_next[4]; + static Arena g_arena; + #endif //PARANOID_USE_ARENA + + }; @@ -241,8 +269,10 @@ namespace IPDF template T ParanoidNumber::Convert() const { - if (!isnan(m_cached_result)) + #ifdef PARANOID_CACHE_RESULTS + if (!isnan((float(m_cached_result)))) return (T)m_cached_result; + #endif T value(m_value); for (auto mul : m_next[MULTIPLY]) {