X-Git-Url: https://git.ucc.asn.au/?p=ipdf%2Fcode.git;a=blobdiff_plain;f=src%2Fparanoidnumber.h;fp=src%2Fparanoidnumber.h;h=9e63a23371b853291d278164b88e922957bf59cb;hp=e88cfe75b9b94439b0b87064a7fb1c8f6e5c1311;hb=0f3a7a9d2c6cc19852fae8ed048dcd1089d33250;hpb=081b38a5f11d0eb093fdf3315051e9c1de7135fd diff --git a/src/paranoidnumber.h b/src/paranoidnumber.h index e88cfe7..9e63a23 100644 --- a/src/paranoidnumber.h +++ b/src/paranoidnumber.h @@ -71,12 +71,12 @@ namespace IPDF public: typedef PARANOID_DIGIT_T digit_t; - ParanoidNumber(digit_t value=0) : m_value(value) + ParanoidNumber(digit_t value=0) : m_value(value), m_cached_result(value) { Construct(); } - ParanoidNumber(const ParanoidNumber & cpy) : m_value(cpy.m_value) + ParanoidNumber(const ParanoidNumber & cpy) : m_value(cpy.m_value), m_cached_result(cpy.m_cached_result) { Construct(); for (int i = 0; i < NOP; ++i) @@ -98,9 +98,12 @@ namespace IPDF template T Convert() const; + digit_t GetFactors(); + digit_t GetTerms(); + - double ToDouble() const {return Convert();} - digit_t Digit() const {return Convert();} + double ToDouble() {return (double)Digit();} + digit_t Digit(); bool Floating() const { @@ -122,14 +125,14 @@ namespace IPDF ParanoidNumber * TrivialOp(ParanoidNumber * b, Optype op); ParanoidNumber * Operation(ParanoidNumber * b, Optype op, ParanoidNumber ** merge_point = NULL, Optype * mop = NULL); bool Simplify(Optype op); + bool FullSimplify(); - - 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));} + 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));} ParanoidNumber operator+(const ParanoidNumber & a) const { @@ -176,7 +179,7 @@ namespace IPDF return copy; } - + static int64_t Paranoia() {return g_count;} std::string PStr() const; @@ -191,29 +194,36 @@ namespace IPDF digit_t m_value; Optype m_op; std::vector m_next[4]; - - int m_size; + digit_t m_cached_result; + bool m_cache_valid; }; + + + template T ParanoidNumber::Convert() const { + if (!isnan(m_cached_result)) + return (T)m_cached_result; T value(m_value); for (auto mul : m_next[MULTIPLY]) { - value *= mul->Digit(); + value *= mul->Convert(); } for (auto div : m_next[DIVIDE]) { - value /= div->Digit(); + value /= div->Convert(); } for (auto add : m_next[ADD]) - value += add->Digit(); + value += add->Convert(); for (auto sub : m_next[SUBTRACT]) - value -= sub->Digit(); + value -= sub->Convert(); return value; } + + } #endif //_PARANOIDNUMBER_H