From 0d71b0cec200b74a3bf4a7addc7cdc84fd29be31 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Sat, 5 Sep 2009 16:43:38 +0000 Subject: [PATCH] merged: AboutEqual() from chk branch deleted: properties svn:mime-type from ttmath.h (it was for testing viewvc) git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@186 e52654a7-88a9-db11-a3e9-0013d4bc506e --- CHANGELOG | 4 ++- ttmath/ttmathbig.h | 71 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index a8bac52..762b2d0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,4 @@ -Version 0.9.0 prerelease (2009.08.04): +Version 0.9.0 prerelease (2009.09.05): * added: support for wide characters (wchar_t) wide characters are used when macro TTMATH_USE_WCHAR is defined this macro is defined automatically when there is macro UNICODE or _UNICODE defined @@ -20,6 +20,8 @@ Version 0.9.0 prerelease (2009.08.04): * added: multithread support for Big<> class you should compile with TTMATH_MULTITHREADS and use TTMATH_MULTITHREADS_HELPER macro somewhere in your *.cpp file + * added: Big::AboutEqual(const Big & ss2, int nBitsToIgnore = 4) + the last nBitsToIgnore bits from mantissas will be skipped when comparing * changed: Factorial() is using the Gamma() function now * removed: Parser<>::SetFactorialMax() method the factorial() is such a fast now that we don't need the method longer diff --git a/ttmath/ttmathbig.h b/ttmath/ttmathbig.h index b65e06a..1688c30 100644 --- a/ttmath/ttmathbig.h +++ b/ttmath/ttmathbig.h @@ -3916,6 +3916,77 @@ public: } + bool AboutEqual(const Big & ss2, int nBitsToIgnore = 4) const + { + // we should check the mantissas beforehand because sometimes we can have + // a mantissa set to zero but in the exponent something another value + // (maybe we've forgotten about calling CorrectZero() ?) + if( mantissa.IsZero() ) + { + if( ss2.mantissa.IsZero() ) + return true; + + return(ss2.AboutEqual(*this,nBitsToIgnore)); + } + + if( ss2.mantissa.IsZero() ) + { + return(this->exponent <= uint(2*(-sint(man*TTMATH_BITS_PER_UINT))+nBitsToIgnore)); + } + + // exponents may not differ much! + ttmath::Int expdiff(this->exponent - ss2.exponent); + + // they may differ one if for example mantissa1=0x80000000, mantissa2=0xffffffff + if( ttmath::Abs(expdiff) > 1 ) + return(false); + + // calculate the 'difference' mantissa + ttmath::UInt man1(this->mantissa); + ttmath::UInt man2(ss2.mantissa); + ttmath::UInt mandiff; + + switch( expdiff.ToInt() ) + { + case +1: + man2.Rcr(1,0); + mandiff = man1; + mandiff.Sub(man2); + break; + case -1: + man1.Rcr(1,0); + mandiff = man2; + mandiff.Sub(man1); + break; + default: + if( man2 > man1 ) + { + mandiff = man2; + mandiff.Sub(man1); + } + else + { + mandiff = man1; + mandiff.Sub(man2); + } + break; + } + + // faster to mask the bits! + TTMATH_ASSERT( nBitsToIgnore < TTMATH_BITS_PER_UINT ); + + for( int n = man-1; n > 0; --n ) + { + if( mandiff.table[n] != 0 ) + return(false); + } + + uint nMask = ~((1 << nBitsToIgnore) - 1); + + return((mandiff.table[0] & nMask) == 0); + } + + bool operator<(const Big & ss2) const { if( IsSign() && !ss2.IsSign() )