X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=src%2Fparanoidnumber.h;h=1ffa97b23d3142b8436e6cd7c9b2c93e27ee19be;hb=ea748154f1bc7dbc81cb52611a52865e63109439;hp=9e63a23371b853291d278164b88e922957bf59cb;hpb=0f3a7a9d2c6cc19852fae8ed048dcd1089d33250;p=ipdf%2Fcode.git diff --git a/src/paranoidnumber.h b/src/paranoidnumber.h index 9e63a23..1ffa97b 100644 --- a/src/paranoidnumber.h +++ b/src/paranoidnumber.h @@ -9,6 +9,8 @@ #include #include #include +#include // it's going to be ok +#include #define PARANOID_DIGIT_T float // we could theoretically replace this with a template // but let's not do that... @@ -71,40 +73,65 @@ namespace IPDF public: typedef PARANOID_DIGIT_T digit_t; - ParanoidNumber(digit_t value=0) : m_value(value), m_cached_result(value) + ParanoidNumber(PARANOID_DIGIT_T value=0) : m_value(value), m_cached_result(value), m_cache_valid(true), m_next() { Construct(); + assert(SanityCheck()); } - ParanoidNumber(const ParanoidNumber & cpy) : m_value(cpy.m_value), m_cached_result(cpy.m_cached_result) + static ParanoidNumber * SafeConstruct(const ParanoidNumber & cpy) + { + ParanoidNumber * result = new ParanoidNumber(cpy); + assert(result != NULL); + assert(result->SanityCheck()); + return result; + } + + 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() { Construct(); for (int i = 0; i < NOP; ++i) { for (auto next : cpy.m_next[i]) - m_next[i].push_back(new ParanoidNumber(*next)); + { + if (next != NULL) // why would this ever be null + m_next[i].push_back(new ParanoidNumber(*next)); // famous last words... + } } + assert(SanityCheck()); } - ParanoidNumber(const char * str); - ParanoidNumber(const std::string & str) : ParanoidNumber(str.c_str()) {} + //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 + { + std::set s; + return SanityCheck(s); + } template T Convert() const; - digit_t GetFactors(); - digit_t GetTerms(); + digit_t GetFactors() const; + digit_t GetTerms() const; - - double ToDouble() {return (double)Digit();} - digit_t Digit(); + // This function is declared const purely to trick the compiler. + // It is not actually const, and therefore, none of the other functions that call it are const either. + digit_t Digit() const; + // Like this one. It isn't const. + double ToDouble() const {return (double)Digit();} + + // This one is probably const. bool Floating() const { return NoFactors() && NoTerms(); @@ -127,12 +154,21 @@ namespace IPDF bool Simplify(Optype op); bool FullSimplify(); - bool operator<(ParanoidNumber & a) {return ToDouble() < a.ToDouble();} - bool operator<=(ParanoidNumber & a) {return this->operator<(a) || this->operator==(a);} - bool operator>(ParanoidNumber & a) {return !(this->operator<=(a));} - bool operator>=(ParanoidNumber & a) {return !(this->operator<(a));} - bool operator==(ParanoidNumber & a) {return ToDouble() == a.ToDouble();} - bool operator!=(ParanoidNumber & a) {return !(this->operator==(a));} + + // None of these are actually const + bool operator<(const ParanoidNumber & a) const {return ToDouble() < a.ToDouble();} + bool operator<=(const ParanoidNumber & a) const {return this->operator<(a) || this->operator==(a);} + bool operator>(const ParanoidNumber & a) const {return !(this->operator<=(a));} + bool operator>=(const ParanoidNumber & a) const {return !(this->operator<(a));} + bool operator==(const ParanoidNumber & a) const {return ToDouble() == a.ToDouble();} + bool operator!=(const ParanoidNumber & a) const {return !(this->operator==(a));} + + ParanoidNumber operator-() const + { + ParanoidNumber neg(0); + neg -= *this; + return neg; + } ParanoidNumber operator+(const ParanoidNumber & a) const { @@ -193,9 +229,10 @@ namespace IPDF digit_t m_value; Optype m_op; - std::vector m_next[4]; + digit_t m_cached_result; bool m_cache_valid; + std::vector m_next[4]; };