X-Git-Url: https://git.ucc.asn.au/?p=ipdf%2Fcode.git;a=blobdiff_plain;f=src%2Fparanoidnumber.cpp;h=60802eb432a7acc0f17c530a42bf7b0461c17f0b;hp=40071e15f89f7585562cdf741e43e51c3b7c5b08;hb=64b7c42c71c35d520424cf4ca5ecaa99faef8b26;hpb=71df61ab8ea302247ad35ccdc973bc8e0cafd5b1 diff --git a/src/paranoidnumber.cpp b/src/paranoidnumber.cpp index 40071e1..60802eb 100644 --- a/src/paranoidnumber.cpp +++ b/src/paranoidnumber.cpp @@ -29,10 +29,10 @@ ParanoidNumber::~ParanoidNumber() ParanoidNumber::ParanoidNumber(const string & str) : m_value(0), m_next() { #ifdef PARANOID_SIZE_LIMIT - m_size = 0; + m_size = 1; #endif #ifdef PARANOID_CACHE_RESULTS - m_cached_result = NAN; + m_cache_valid = false; #endif int dp = 0; @@ -85,8 +85,9 @@ ParanoidNumber & ParanoidNumber::operator=(const ParanoidNumber & a) #endif m_value = a.m_value; - #ifdef PARANOID_CACHE_RESULT + #ifdef PARANOID_CACHE_RESULTS m_cached_result = a.m_cached_result; + m_cache_valid = a.m_cache_valid; #endif for (int i = 0; i < NOP; ++i) { @@ -411,8 +412,9 @@ ParanoidNumber & ParanoidNumber::operator=(const digit_t & a) m_next[i].clear(); } m_value = a; - #ifdef PARANOID_CACHE_RESULT + #ifdef PARANOID_CACHE_RESULTS m_cached_result = a; + m_cache_valid = true; #endif #ifdef PARANOID_COMPARE_EPSILON @@ -427,19 +429,21 @@ ParanoidNumber * ParanoidNumber::OperationTerm(ParanoidNumber * b, Optype op, Pa { ////assert(b->SanityCheck()); #ifdef PARANOID_CACHE_RESULTS - m_cached_result = NAN; + m_cache_valid = false; #endif #ifdef PARANOID_SIZE_LIMIT - if (m_size >= PARANOID_SIZE_LIMIT) + if (m_size + b->m_size >= PARANOID_SIZE_LIMIT) { + this->operator=(this->Digit()); if (op == ADD) - { - m_value += b->Digit() / GetFactors(); - } + m_value += b->Digit(); else - { - m_value -= b->Digit() / GetFactors(); - } + m_value -= b->Digit(); + m_size = 1; + #ifdef PARANOID_CACHE_RESULTS + m_cached_result = m_value; + m_cache_valid = true; + #endif return b; } //Debug("At size limit %d", m_size); @@ -542,7 +546,7 @@ ParanoidNumber * ParanoidNumber::OperationTerm(ParanoidNumber * b, Optype op, Pa //merge->m_next[*merge_op].push_back(b); m_next[op].push_back(b); #ifdef PARANOID_SIZE_LIMIT - m_size += 1+b->m_size; + m_size += b->m_size; #endif } else @@ -562,20 +566,22 @@ ParanoidNumber * ParanoidNumber::OperationTerm(ParanoidNumber * b, Optype op, Pa ParanoidNumber * ParanoidNumber::OperationFactor(ParanoidNumber * b, Optype op, ParanoidNumber ** merge_point, Optype * merge_op) { #ifdef PARANOID_CACHE_RESULTS - m_cached_result = NAN; + m_cache_valid = false; #endif #ifdef PARANOID_SIZE_LIMIT - if (m_size >= PARANOID_SIZE_LIMIT) + if (m_size + b->m_size >= PARANOID_SIZE_LIMIT) { + this->operator=(this->Digit()); if (op == MULTIPLY) m_value *= b->Digit(); else m_value /= b->Digit(); - - for (auto n : m_next[ADD]) - delete n->OperationFactor(new ParanoidNumber(*b), op); - for (auto n : m_next[SUBTRACT]) - delete n->OperationFactor(new ParanoidNumber(*b), op); + m_size = 1; + #ifdef PARANOID_CACHE_RESULTS + m_cached_result = m_value; + m_cache_valid = true; + #endif + //Debug("Cut off %p", this); return b; } @@ -692,7 +698,7 @@ ParanoidNumber * ParanoidNumber::OperationFactor(ParanoidNumber * b, Optype op, delete(sub->OperationFactor(new ParanoidNumber(*cpy_b), op)); #ifdef PARANOID_SIZE_LIMIT - m_size += 1+b->m_size; + m_size += b->m_size; #endif } //assert(SanityCheck()); @@ -785,7 +791,7 @@ bool ParanoidNumber::Simplify(Optype op) if (result != NULL) { #ifdef PARANOID_SIZE_LIMIT - m_size -= (1+result->m_size); + m_size -= result->m_size; #endif *m = NULL; delete(result); @@ -802,7 +808,7 @@ bool ParanoidNumber::Simplify(Optype op) #ifdef PARANOID_SIZE_LIMIT if (Operation(n, op) == n) { - m_size -= (1+n->m_size); + m_size -= n->m_size; delete n; } #else @@ -840,10 +846,11 @@ ParanoidNumber::digit_t ParanoidNumber::Digit() const // Get around the absurd requirement that const correctness be observed. #ifdef PARANOID_CACHE_RESULTS + if (m_cache_valid) // le sigh ambiguous function compiler warnings + return m_cached_result; + digit_t & result = ((ParanoidNumber*)(this))->m_cached_result; - if (!isnan(float(result))) // le sigh ambiguous function compiler warnings - return result; #else digit_t result; #endif @@ -860,6 +867,10 @@ ParanoidNumber::digit_t ParanoidNumber::Digit() const result += add->Digit(); for (auto sub : m_next[SUBTRACT]) result -= sub->Digit(); + + #ifdef PARANOID_CACHE_RESULTS + ((ParanoidNumber*)(this))->m_cache_valid = true; + #endif return result; } @@ -934,6 +945,9 @@ void ParanoidNumber::Negate() { swap(m_next[ADD], m_next[SUBTRACT]); m_value = -m_value; + #ifdef PARANOID_CACHE_RESULTS + m_cached_result = -m_cached_result; + #endif } #ifdef PARANOID_USE_ARENA