+ #ifdef PARANOID_COMPARE_EPSILON
+ digit_t compare = Digit();
+ compare /= a.Digit();
+ #endif
+ delete Operation(new ParanoidNumber(a), DIVIDE);
+ Simplify(MULTIPLY);
+ Simplify(DIVIDE);
+ #ifdef PARANOID_COMPARE_EPSILON
+ CompareForSanity(compare, a.Digit());
+ #endif
+ return *this;
+}
+
+ParanoidNumber & ParanoidNumber::operator=(const digit_t & a)
+{
+
+ for (int i = 0; i < NOP; ++i)
+ {
+ for (auto n : m_next[i])
+ delete n;
+ m_next[i].clear();
+ }
+ m_value = a;
+ #ifdef PARANOID_CACHE_RESULTS
+ m_cached_result = a;
+ m_cache_valid = true;
+ #endif
+
+ #ifdef PARANOID_COMPARE_EPSILON
+ CompareForSanity(a,a);
+ #endif
+
+ return *this;
+}
+
+// a + b
+ParanoidNumber * ParanoidNumber::OperationTerm(ParanoidNumber * b, Optype op, ParanoidNumber ** merge_point, Optype * merge_op)
+{
+ ////assert(b->SanityCheck());
+ #ifdef PARANOID_CACHE_RESULTS
+ m_cache_valid = false;
+ #endif
+ #ifdef 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 = 1;
+ #ifdef PARANOID_CACHE_RESULTS
+ m_cached_result = m_value;
+ m_cache_valid = true;
+ #endif
+ return b;
+ }
+ //Debug("At size limit %d", m_size);
+ #endif
+
+
+ if (Floating() && m_value == 0) // 0 + b = b
+ {
+ m_value = b->m_value;
+ if (op == SUBTRACT)
+ {
+ m_value = -m_value;
+ swap(b->m_next[ADD], b->m_next[SUBTRACT]);
+ }
+
+ for (int i = 0; i < NOP; ++i)
+ {
+ m_next[i] = b->m_next[i];
+ b->m_next[i].clear();
+ }
+
+ //assert(SanityCheck());
+ return b;
+ }
+ if (b->Floating() && b->m_value == 0) // a + 0 = a
+ return b;