diff --git a/CHANGELOG b/CHANGELOG index ad45d2c..a689369 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,13 +1,13 @@ -Version 0.9.1 prerelease (2009.12.06): +Version 0.9.1 prerelease (2009.12.25): * fixed: the parser didn't use characters for changing the base (# and &) those characters were skipped (this bug was introduced in 0.9.0) + * fixed: added in the parser: operator's associativity + operator ^ (powering) is right-associative: + sample: 2^3^4 is equal 2^(3^4) and it is: 2.41e+24 + previously was: 2^3^4 = (2^3)^4 = 4096 * added: IEEE 754 half-to-even rounding (bankers' rounding) to the following - floating point algorithms: - Big::Add - Big::Sub - Big::Mul - Big::Div + floating point algorithms: Big::Add, Big::Sub, Big::Mul, Big::Div * added: to Big::ToString() - additional rounding when conv.base_round is used if the value is not an integer we calculate how many valid digits there are after the comma operator (in conv.base radix) and then we skipped the rest diff --git a/ttmath/ttmathbig.h b/ttmath/ttmathbig.h index 9789468..6d46ddd 100644 --- a/ttmath/ttmathbig.h +++ b/ttmath/ttmathbig.h @@ -1575,7 +1575,7 @@ public: if( pow.Mod2() ) c += result.Mul(start); - c += pow.exponent.Sub( e_one ); + c += pow.exponent.Sub( e_one ); // !! may use SubOne() here? if( pow < one ) break; diff --git a/ttmath/ttmathparser.h b/ttmath/ttmathparser.h index 08f7904..e3f18ac 100644 --- a/ttmath/ttmathparser.h +++ b/ttmath/ttmathparser.h @@ -159,14 +159,20 @@ private: none,add,sub,mul,div,pow,lt,gt,let,get,eq,neq,lor,land,shortmul }; + enum Assoc + { + right, // right-associative + non_right // associative or left-associative + }; - Type GetType() const { return type; } - int GetPriority() const { return priority; } - + Type GetType() const { return type; } + int GetPriority() const { return priority; } + Assoc GetAssoc() const { return assoc; } void SetType(Type t) { - type = t; + type = t; + assoc = non_right; switch( type ) { @@ -200,6 +206,7 @@ private: case pow: priority = 14; + assoc = right; break; default: @@ -208,15 +215,15 @@ private: } } - MatOperator(): type(none), priority(0) + MatOperator(): type(none), priority(0), assoc(non_right) { } private: - Type type; - int priority; - + Type type; + int priority; + Assoc assoc; }; // end of MatOperator class @@ -2207,10 +2214,20 @@ void TryRollingUpStackWithOperatorPriority() { while( stack_index>=4 && stack[stack_index-4].type == Item::numerical_value && - stack[stack_index-3].type == Item::mat_operator && + stack[stack_index-3].type == Item::mat_operator && stack[stack_index-2].type == Item::numerical_value && - stack[stack_index-1].type == Item::mat_operator && - stack[stack_index-3].moperator.GetPriority() >= stack[stack_index-1].moperator.GetPriority() + stack[stack_index-1].type == Item::mat_operator && + ( + ( + // the first operator has greater priority + stack[stack_index-3].moperator.GetPriority() > stack[stack_index-1].moperator.GetPriority() + ) || + ( + // or both operators have the same priority and the first operator is not right associative + stack[stack_index-3].moperator.GetPriority() == stack[stack_index-1].moperator.GetPriority() && + stack[stack_index-3].moperator.GetAssoc() == MatOperator::non_right + ) + ) ) { MakeStandardMathematicOperation(stack[stack_index-4].value,