From 2116418f08e623def008f376b56d12cd4cd00490 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Fri, 13 Apr 2007 18:14:11 +0000 Subject: [PATCH] added: UInt::BitAnd(), UInt::BitOr(), UInt::BitXor(), UInt::BitNot(), Big::BitAnd(), Big::BitOr(), Big::BitXor() added: to the parser: bitand(), bitor(), bitxor() /band(), bor(), bxor()/ git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@36 e52654a7-88a9-db11-a3e9-0013d4bc506e --- TODO | 4 +- ttmath/ttmathbig.h | 139 ++++++++++++++++++++++++++++++++++++++++++ ttmath/ttmathparser.h | 67 ++++++++++++++++++++ ttmath/ttmathuint.h | 44 ++++++++++++- 4 files changed, 250 insertions(+), 4 deletions(-) diff --git a/TODO b/TODO index 4be364f..60522a8 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,5 @@ TODO TTMath Library =================== -* Add bitwise operators (or functions) and, or, xor * Add functions for generating random values - - +* Add something like NaN to the Big<> type diff --git a/ttmath/ttmathbig.h b/ttmath/ttmathbig.h index aa4fa43..7a6c47c 100644 --- a/ttmath/ttmathbig.h +++ b/ttmath/ttmathbig.h @@ -616,6 +616,145 @@ public: } + /*! + bitwise AND + + this and ss2 must be >= 0 + return values: + 0 - ok + 1 - carry + 2 - this or ss2 was negative + */ + uint BitAnd(Big ss2) + { + if( IsSign() || ss2.IsSign() ) + return 2; + + Int exp_offset( exponent ); + Int mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT ); + + uint c = 0; + + exp_offset.Sub( ss2.exponent ); + exp_offset.Abs(); + + // abs(this) will be >= abs(ss2) + if( SmallerWithoutSignThan(ss2) ) + { + Big temp(ss2); + + ss2 = *this; + *this = temp; + } + + if( exp_offset >= mantissa_size_in_bits ) + { + // the second value is too short + SetZero(); + return 0; + } + + // exp_offset < mantissa_size_in_bits, moving 'exp_offset' times + ss2.mantissa.Rcr( exp_offset.ToInt(), 0 ); + mantissa.BitAnd(ss2.mantissa); + + c += Standardizing(); + + return (c==0)? 0 : 1; + } + + + /*! + bitwise OR + + this and ss2 must be >= 0 + return values: + 0 - ok + 1 - carry + 2 - this or ss2 was negative + */ + uint BitOr(Big ss2) + { + if( IsSign() || ss2.IsSign() ) + return 2; + + Int exp_offset( exponent ); + Int mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT ); + + uint c = 0; + + exp_offset.Sub( ss2.exponent ); + exp_offset.Abs(); + + // abs(this) will be >= abs(ss2) + if( SmallerWithoutSignThan(ss2) ) + { + Big temp(ss2); + + ss2 = *this; + *this = temp; + } + + if( exp_offset >= mantissa_size_in_bits ) + // the second value is too short + return 0; + + // exp_offset < mantissa_size_in_bits, moving 'exp_offset' times + ss2.mantissa.Rcr( exp_offset.ToInt(), 0 ); + mantissa.BitOr(ss2.mantissa); + + c += Standardizing(); + + return (c==0)? 0 : 1; + } + + + /*! + bitwise XOR + + this and ss2 must be >= 0 + return values: + 0 - ok + 1 - carry + 2 - this or ss2 was negative + */ + uint BitXor(Big ss2) + { + if( IsSign() || ss2.IsSign() ) + return 2; + + Int exp_offset( exponent ); + Int mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT ); + + uint c = 0; + + exp_offset.Sub( ss2.exponent ); + exp_offset.Abs(); + + // abs(this) will be >= abs(ss2) + if( SmallerWithoutSignThan(ss2) ) + { + Big temp(ss2); + + ss2 = *this; + *this = temp; + } + + if( exp_offset >= mantissa_size_in_bits ) + // the second value is too short + return 0; + + // exp_offset < mantissa_size_in_bits, moving 'exp_offset' times + ss2.mantissa.Rcr( exp_offset.ToInt(), 0 ); + mantissa.BitXor(ss2.mantissa); + + c += Standardizing(); + + return (c==0)? 0 : 1; + } + + + /*! Multiplication this = this * ss2 (ss2 is uint) diff --git a/ttmath/ttmathparser.h b/ttmath/ttmathparser.h index 4de664b..2a8f008 100644 --- a/ttmath/ttmathparser.h +++ b/ttmath/ttmathparser.h @@ -1097,6 +1097,67 @@ void ACoth(int sindex, int amount_of_args, ValueType & result) } +void BitAnd(int sindex, int amount_of_args, ValueType & result) +{ + if( amount_of_args != 2 ) + Error( err_improper_amount_of_arguments ); + + uint err; + result = stack[sindex].value; + err = result.BitAnd(stack[sindex+2].value); + + switch(err) + { + case 1: + Error( err_overflow ); + break; + case 2: + Error( err_improper_argument ); + break; + } +} + +void BitOr(int sindex, int amount_of_args, ValueType & result) +{ + if( amount_of_args != 2 ) + Error( err_improper_amount_of_arguments ); + + uint err; + result = stack[sindex].value; + err = result.BitOr(stack[sindex+2].value); + + switch(err) + { + case 1: + Error( err_overflow ); + break; + case 2: + Error( err_improper_argument ); + break; + } +} + + +void BitXor(int sindex, int amount_of_args, ValueType & result) +{ + if( amount_of_args != 2 ) + Error( err_improper_amount_of_arguments ); + + uint err; + result = stack[sindex].value; + err = result.BitXor(stack[sindex+2].value); + + switch(err) + { + case 1: + Error( err_overflow ); + break; + case 2: + Error( err_improper_argument ); + break; + } +} + /*! this method returns the value from a user-defined function @@ -1252,6 +1313,12 @@ void CreateFunctionsTable() InsertFunctionToTable(std::string("atgh"), &Parser::ATanh); InsertFunctionToTable(std::string("acoth"), &Parser::ACoth); InsertFunctionToTable(std::string("actgh"), &Parser::ACoth); + InsertFunctionToTable(std::string("bitand"), &Parser::BitAnd); + InsertFunctionToTable(std::string("bitor"), &Parser::BitOr); + InsertFunctionToTable(std::string("bitxor"), &Parser::BitXor); + InsertFunctionToTable(std::string("band"), &Parser::BitAnd); + InsertFunctionToTable(std::string("bor"), &Parser::BitOr); + InsertFunctionToTable(std::string("bxor"), &Parser::BitXor); } diff --git a/ttmath/ttmathuint.h b/ttmath/ttmathuint.h index cff7098..8e0cefb 100644 --- a/ttmath/ttmathuint.h +++ b/ttmath/ttmathuint.h @@ -1489,6 +1489,48 @@ public: } + /*! + this method performs a bitwise operation AND + */ + void BitAnd(const UInt & ss2) + { + for(uint x=0 ; x & ss2) + { + for(uint x=0 ; x & ss2) + { + for(uint x=0 ; x