X-Git-Url: https://git.ucc.asn.au/?p=ipdf%2Fcode.git;a=blobdiff_plain;f=src%2Fparanoidnumber.cpp;h=60802eb432a7acc0f17c530a42bf7b0461c17f0b;hp=efae86003e6ddefd36f5b071db370a6c78243b87;hb=64b7c42c71c35d520424cf4ca5ecaa99faef8b26;hpb=f8b8daf1828b8a8028b9344dd0feca1b8d9e859a diff --git a/src/paranoidnumber.cpp b/src/paranoidnumber.cpp index efae860..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,18 +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(); else m_value -= b->Digit(); - m_size = 0; - Debug("Cut off %p", this); + 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); @@ -541,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 @@ -561,19 +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(); - m_size = 0; - - Debug("Cut off %p", this); + m_size = 1; + #ifdef PARANOID_CACHE_RESULTS + m_cached_result = m_value; + m_cache_valid = true; + #endif + //Debug("Cut off %p", this); return b; } @@ -690,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()); @@ -783,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); @@ -800,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 @@ -838,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 @@ -858,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; } @@ -932,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