From 418db51f46c55c8323c3897adc27e168f2931dc2 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Mon, 14 Dec 2009 12:16:32 +0000 Subject: [PATCH] added: to Big::Add Big::Sub Big::Mul Big::Div second parameter 'bool round = true' the rounding is made if it is true changed: in Big::ToString_CreateNewMantissaAndExponent() we should use dividing without rounding consider this 32 bit binary value: 1.1111111111111111111111111111111 previous the result from converting (to the base 10) was equal 2 now is 1.999999 git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@263 e52654a7-88a9-db11-a3e9-0013d4bc506e --- ttmath/ttmathbig.h | 42 +++++++++++++++++------------------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/ttmath/ttmathbig.h b/ttmath/ttmathbig.h index 4d4dc1a..1b5044a 100644 --- a/ttmath/ttmathbig.h +++ b/ttmath/ttmathbig.h @@ -869,7 +869,7 @@ public: it returns carry if the sum is too big */ - uint Add(Big ss2) + uint Add(Big ss2, bool round = true) { Int exp_offset( exponent ); @@ -904,7 +904,7 @@ public: if( do_adding ) c += AddMantissas(ss2, last_bit_set, rest_zero, do_rounding, rounding_up); - if( do_rounding && last_bit_set ) + if( round && do_rounding && last_bit_set ) c += RoundHalfToEven(rest_zero, rounding_up); if( do_adding || (do_rounding && last_bit_set) ) @@ -919,11 +919,11 @@ public: it returns carry if the result is too big */ - uint Sub(Big ss2) + uint Sub(Big ss2, bool round = true) { ss2.ChangeSign(); - return Add(ss2); + return Add(ss2, round); } @@ -1233,7 +1233,7 @@ public: multiplication this = this * ss2 this method returns a carry */ - uint Mul(const Big & ss2) + uint Mul(const Big & ss2, bool round = true) { TTMATH_REFERENCE_ASSERT( ss2 ) @@ -1272,7 +1272,7 @@ public: for(i=0 ; i & ss2) + uint Div(const Big & ss2, bool round = true) { TTMATH_REFERENCE_ASSERT( ss2 ) @@ -1348,10 +1348,10 @@ public: for(i=0 ; i new_exp; - if( ToString_CreateNewMantissaAndExponent(result, conv, new_exp) ) + if( ToString_CreateNewMantissaAndExponent(result, conv, new_exp) ) { Misc::AssignString(result, error_overflow_msg); return 1; } - /* - we're rounding the mantissa only if the base is different from 2,4,8 or 16 - (this formula means that the number of bits in the base is greater than one) - */ - if( conv.base_round && conv.base!=2 && conv.base!=4 && conv.base!=8 && conv.base!=16 ) - { - if( ToString_BaseRound(result, conv, new_exp) ) - { - Misc::AssignString(result, error_overflow_msg); - return 1; - } - } if( ToString_SetCommaAndExponent(result, conv, new_exp) ) { @@ -3313,7 +3301,7 @@ private: M = mm * 2^ee where ee will be <= 0 next we'll move all bits of mm into the right when ee is equal zero - abs(ee) must not to be too big that only few bits from mm we can leave + abs(ee) must not be too big that only few bits from mm we can leave then we'll have: M = mmm * 2^0 @@ -3327,7 +3315,7 @@ private: but we need 'new'exp' as integer then we take: new_exp = [log base (2^exponent)] + 1 <- where [x] means integer value from x */ - template + template uint ToString_CreateNewMantissaAndExponent( string_type & new_man, const Conv & conv, Int & new_exp) const { @@ -3389,7 +3377,7 @@ private: // the sign don't interest us here temp.mantissa = mantissa; temp.exponent = exponent; - c += temp.Div( base_ ); + c += temp.Div(base_, false); // dividing without rounding // moving all bits of the mantissa into the right // (how many times to move depend on the exponent) @@ -3406,6 +3394,10 @@ private: // shouldn't have had a carry // (in the future this can be changed) + // base rounding + if( conv.base_round ) + c += ToString_BaseRound(new_man, conv, new_exp); + return (c==0)? 0 : 1; }