diff options
author | Wolfgang Pechlaner <libo@pechlaner.at> | 2011-09-04 14:40:25 +0200 |
---|---|---|
committer | Eike Rathke <erack@erack.de> | 2011-09-07 12:27:27 +0200 |
commit | c6b49f9098fb6c9816202e8d465c342788736af5 (patch) | |
tree | d1074becd133921d5dc77cf3afe9f1ac74516c67 | |
parent | 5b80048a1ef119db569f9e9a259e94e773201b1f (diff) |
BITxxx functions according to ODF 1.2 OpenFormula
Implements BITAND, BITOR, BITXOR, BITLSHIFT and BITRSHIFT as specified by
OASIS OpenDocument Format 1.2 OpenFormula / ODFF.
Changes made by the committer:
* Original submission added the new functions to the Logical group, that group
has only functions though that return a logical value 1/0/true/false. ODFF
groups them under "Bit operation functions" that currently is not available
in Calc. Added the functions to the Mathematical group instead.
* Changed descriptions of functions in the Function Wizard.
* One sal_uInt64 constant instead of several identical literal 281474976710655
values.
* Replaced 'or' operators with ||
* Don't push two return values, if PushIllegalArgument() was used don't use
PushDouble() thereafter.
* Treat double values with ::rtl::math::approxFloor() to obtain integer
values.
* For BITLSHIFT and BITRSHIFT implemented a different algorithm following the
ODFF specification that allows larger shift values.
* Use our block braces style, respectively don't use block braces for one-line
if-statements.
* Fixed indentation levels.
* Adapted RTL_LOGFILE_CONTEXT_AUTHOR to say "pechlaner". Credit to whom credit
is due ;-)
-rwxr-xr-x | formula/inc/formula/compiler.hrc | 10 | ||||
-rw-r--r-- | formula/inc/formula/opcode.hxx | 6 | ||||
-rw-r--r-- | formula/source/core/resource/core_resource.src | 32 | ||||
-rw-r--r-- | sc/inc/helpids.h | 5 | ||||
-rw-r--r-- | sc/qa/unit/ucalc.cxx | 5 | ||||
-rw-r--r-- | sc/source/core/inc/interpre.hxx | 5 | ||||
-rw-r--r-- | sc/source/core/tool/interpr1.cxx | 103 | ||||
-rw-r--r-- | sc/source/core/tool/interpr4.cxx | 5 | ||||
-rw-r--r-- | sc/source/ui/src/scfuncs.src | 156 | ||||
-rw-r--r-- | sc/util/hidother.src | 5 |
10 files changed, 327 insertions, 5 deletions
diff --git a/formula/inc/formula/compiler.hrc b/formula/inc/formula/compiler.hrc index 5c58d9d3e068..a7b5cd808f88 100755 --- a/formula/inc/formula/compiler.hrc +++ b/formula/inc/formula/compiler.hrc @@ -392,9 +392,13 @@ #define SC_OPCODE_NUMBERVALUE 392 #define SC_OPCODE_CHISQ_DIST 393 #define SC_OPCODE_CHISQ_INV 394 -#define SC_OPCODE_STOP_2_PAR 395 - -#define SC_OPCODE_LAST_OPCODE_ID 394 /* last OpCode */ +#define SC_OPCODE_BITAND 395 +#define SC_OPCODE_BITOR 396 +#define SC_OPCODE_BITXOR 397 +#define SC_OPCODE_BITRSHIFT 398 +#define SC_OPCODE_BITLSHIFT 399 +#define SC_OPCODE_STOP_2_PAR 400 +#define SC_OPCODE_LAST_OPCODE_ID 399 /* last OpCode */ /*** Interna ***/ #define SC_OPCODE_INTERNAL_BEGIN 9999 diff --git a/formula/inc/formula/opcode.hxx b/formula/inc/formula/opcode.hxx index fc9a9b7cf525..571e1b00c247 100644 --- a/formula/inc/formula/opcode.hxx +++ b/formula/inc/formula/opcode.hxx @@ -365,6 +365,12 @@ enum OpCodeEnum ocTableOp = SC_OPCODE_TABLE_OP, ocBetaDist = SC_OPCODE_BETA_DIST, ocBetaInv = SC_OPCODE_BETA_INV, + // Bit functions + ocBitAnd = SC_OPCODE_BITAND, + ocBitOr = SC_OPCODE_BITOR, + ocBitXor = SC_OPCODE_BITXOR, + ocBitRshift = SC_OPCODE_BITRSHIFT, + ocBitLshift = SC_OPCODE_BITLSHIFT, // miscellaneous ocWeek = SC_OPCODE_WEEK, ocGetDayOfWeek = SC_OPCODE_GET_DAY_OF_WEEK, diff --git a/formula/source/core/resource/core_resource.src b/formula/source/core/resource/core_resource.src index b8a5f1250941..e42a06db4f4f 100644 --- a/formula/source/core/resource/core_resource.src +++ b/formula/source/core/resource/core_resource.src @@ -344,7 +344,11 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH_ODFF String SC_OPCODE_GAMMA { Text = "GAMMA" ; }; String SC_OPCODE_CHISQ_DIST { Text = "CHISQDIST" ; }; String SC_OPCODE_CHISQ_INV { Text = "CHISQINV" ;}; - + String SC_OPCODE_BITAND { Text = "BITAND" ;}; + String SC_OPCODE_BITOR { Text = "BITOR" ;}; + String SC_OPCODE_BITXOR { Text = "BITXOR" ;}; + String SC_OPCODE_BITRSHIFT { Text = "BITRSHIFT" ;}; + String SC_OPCODE_BITLSHIFT { Text = "BITLSHIFT" ;}; /* BEGIN defined ERROR.TYPE() values. */ String SC_OPCODE_ERROR_NULL { Text = "#NULL!" ; }; String SC_OPCODE_ERROR_DIVZERO { Text = "#DIV/0!" ; }; @@ -672,7 +676,11 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH String SC_OPCODE_GAMMA { Text = "GAMMA" ; }; String SC_OPCODE_CHISQ_DIST { Text = "CHISQDIST" ; }; String SC_OPCODE_CHISQ_INV { Text = "CHISQINV" ;}; - + String SC_OPCODE_BITAND { Text = "BITAND" ;}; + String SC_OPCODE_BITOR { Text = "BITOR" ;}; + String SC_OPCODE_BITXOR { Text = "BITXOR" ;}; + String SC_OPCODE_BITRSHIFT { Text = "BITRSHIFT" ;}; + String SC_OPCODE_BITLSHIFT { Text = "BITLSHIFT" ;}; /* BEGIN defined ERROR.TYPE() values. */ String SC_OPCODE_ERROR_NULL { Text = "#NULL!" ; }; String SC_OPCODE_ERROR_DIVZERO { Text = "#DIV/0!" ; }; @@ -1860,6 +1868,26 @@ Resource RID_STRLIST_FUNCTION_NAMES { Text [ en-US ] = "CHISQINV" ; }; + String SC_OPCODE_BITAND + { + Text [ en-US ] = "BITAND" ; + }; + String SC_OPCODE_BITOR + { + Text [ en-US ] = "BITOR" ; + }; + String SC_OPCODE_BITXOR + { + Text [ en-US ] = "BITXOR" ; + }; + String SC_OPCODE_BITRSHIFT + { + Text [ en-US ] = "BITRSHIFT" ; + }; + String SC_OPCODE_BITLSHIFT + { + Text [ en-US ] = "BITLSHIFT" ; + }; /* BEGIN defined ERROR.TYPE() values. */ /* ERROR.TYPE( #NULL! ) == 1 */ String SC_OPCODE_ERROR_NULL diff --git a/sc/inc/helpids.h b/sc/inc/helpids.h index c80dd1bda5a0..5546cf838789 100644 --- a/sc/inc/helpids.h +++ b/sc/inc/helpids.h @@ -692,3 +692,8 @@ #define HID_FUNC_UNICODE "SC_HID_FUNC_UNICODE" #define HID_FUNC_UNICHAR "SC_HID_FUNC_UNICHAR" #define HID_FUNC_NUMBERVALUE "SC_HID_FUNC_NUMBERVALUE" +#define HID_FUNC_BITAND "SC_HID_FUNC_BITAND" +#define HID_FUNC_BITOR "SC_HID_FUNC_BITOR" +#define HID_FUNC_BITXOR "SC_HID_FUNC_BITXOR" +#define HID_FUNC_BITLSHIFT "SC_HID_FUNC_BITLSHIFT" +#define HID_FUNC_BITRSHIFT "SC_HID_FUNC_BITRSHIFT" diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx index e32c28b7906d..ec03cd62d37a 100644 --- a/sc/qa/unit/ucalc.cxx +++ b/sc/qa/unit/ucalc.cxx @@ -1764,6 +1764,11 @@ void Test::testFunctionLists() "ATAN", "ATAN2", "ATANH", + "BITAND", + "BITLSHIFT", + "BITOR", + "BITRSHIFT", + "BITXOR", "CEILING", "COMBIN", "COMBINA", diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx index 27027d56be95..a693f5828ede 100644 --- a/sc/source/core/inc/interpre.hxx +++ b/sc/source/core/inc/interpre.hxx @@ -557,6 +557,11 @@ void ScColRowNameAuto(); void ScGetPivotData(); void ScHyperLink(); void ScBahtText(); +void ScBitAnd(); +void ScBitOr(); +void ScBitXor(); +void ScBitRshift(); +void ScBitLshift(); void ScTTT(); //----------------Funktionen in interpr2.cxx--------------- diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx index f581ac7a84d0..3d6b5c3ed283 100644 --- a/sc/source/core/tool/interpr1.cxx +++ b/sc/source/core/tool/interpr1.cxx @@ -77,6 +77,8 @@ #define SC_DOUBLE_MAXVALUE 1.7e307 +static const sal_uInt64 n2power48 = 281474976710656; // 2^48 + IMPL_FIXEDMEMPOOL_NEWDEL( ScTokenStack, 8, 4 ) IMPL_FIXEDMEMPOOL_NEWDEL( ScInterpreter, 32, 16 ) @@ -1449,6 +1451,107 @@ void ScInterpreter::ScNot() } +void ScInterpreter::ScBitAnd() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "pechlaner", "ScInterpreter::ScBitAnd" ); + + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + + double num1 = ::rtl::math::approxFloor( GetDouble()); + double num2 = ::rtl::math::approxFloor( GetDouble()); + if ( (num1 >= n2power48) || (num1 < 0) || + (num2 >= n2power48) || (num2 < 0)) + PushIllegalArgument(); + else + PushDouble ((sal_uInt64) num1 & (sal_uInt64) num2); +} + + +void ScInterpreter::ScBitOr() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "pechlaner", "ScInterpreter::ScBitOr" ); + + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + + double num1 = ::rtl::math::approxFloor( GetDouble()); + double num2 = ::rtl::math::approxFloor( GetDouble()); + if ( (num1 >= n2power48) || (num1 < 0) || + (num2 >= n2power48) || (num2 < 0)) + PushIllegalArgument(); + else + PushDouble ((sal_uInt64) num1 | (sal_uInt64) num2); +} + + +void ScInterpreter::ScBitXor() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "pechlaner", "ScInterpreter::ScBitXor" ); + + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + + double num1 = ::rtl::math::approxFloor( GetDouble()); + double num2 = ::rtl::math::approxFloor( GetDouble()); + if ( (num1 >= n2power48) || (num1 < 0) || + (num2 >= n2power48) || (num2 < 0)) + PushIllegalArgument(); + else + PushDouble ((sal_uInt64) num1 ^ (sal_uInt64) num2); +} + + +void ScInterpreter::ScBitLshift() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "pechlaner", "ScInterpreter::ScBitLshift" ); + + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + + double fShift = ::rtl::math::approxFloor( GetDouble()); + double num = ::rtl::math::approxFloor( GetDouble()); + if ((num >= n2power48) || (num < 0)) + PushIllegalArgument(); + else + { + double fRes; + if (fShift < 0) + fRes = ::rtl::math::approxFloor( num / pow( 2.0, -fShift)); + else if (fShift == 0) + fRes = num; + else + fRes = num * pow( 2.0, fShift); + PushDouble( fRes); + } +} + + +void ScInterpreter::ScBitRshift() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "pechlaner", "ScInterpreter::ScBitRshift" ); + + if ( !MustHaveParamCount( GetByte(), 2 ) ) + return; + + double fShift = ::rtl::math::approxFloor( GetDouble()); + double num = ::rtl::math::approxFloor( GetDouble()); + if ((num >= n2power48) || (num < 0)) + PushIllegalArgument(); + else + { + double fRes; + if (fShift < 0) + fRes = num * pow( 2.0, -fShift); + else if (fShift == 0) + fRes = num; + else + fRes = ::rtl::math::approxFloor( num / pow( 2.0, fShift)); + PushDouble( fRes); + } +} + + void ScInterpreter::ScPi() { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScPi" ); diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx index 05ff646b5514..5a3e81dcd9fe 100644 --- a/sc/source/core/tool/interpr4.cxx +++ b/sc/source/core/tool/interpr4.cxx @@ -4063,6 +4063,11 @@ StackVar ScInterpreter::Interpret() case ocAsc : ScAsc(); break; case ocUnicode : ScUnicode(); break; case ocUnichar : ScUnichar(); break; + case ocBitAnd : ScBitAnd(); break; + case ocBitOr : ScBitOr(); break; + case ocBitXor : ScBitXor(); break; + case ocBitRshift : ScBitRshift(); break; + case ocBitLshift : ScBitLshift(); break; case ocTTT : ScTTT(); break; case ocNone : nFuncFmtType = NUMBERFORMAT_UNDEFINED; break; default : PushError( errUnknownOpCode); break; diff --git a/sc/source/ui/src/scfuncs.src b/sc/source/ui/src/scfuncs.src index 4f99f90b8437..8f8bb04e5be1 100644 --- a/sc/source/ui/src/scfuncs.src +++ b/sc/source/ui/src/scfuncs.src @@ -9037,6 +9037,162 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2 Text [ en-US ] = "Defines the character used as the decimal point." ; }; }; + + Resource SC_OPCODE_BITAND + { + String 1 // Description + { + Text [ en-US ] = "Bitwise \"AND\" of two integers."; + }; + ExtraData = + { + 0; + ID_FUNCTION_GRP_MATH; + U2S( HID_FUNC_BITAND ); + 2; 0; 0; + 0; + }; + String 2 // Name of Parameter 1 + { + Text [ en-US ] = "Number" ; + }; + String 3 // Description of Parameter 1 + { + Text [ en-US ] = "Positive integer less than 2^48." ; + }; + String 4 // Name of Parameter 2 + { + Text [ en-US ] = "Number" ; + }; + String 5 // Description of Parameter 2 + { + Text [ en-US ] = "Positive integer less than 2^48." ; + }; + }; + Resource SC_OPCODE_BITOR + { + String 1 // Description + { + Text [ en-US ] = "Bitwise \"OR\" of two integers."; + }; + ExtraData = + { + 0; + ID_FUNCTION_GRP_MATH; + U2S( HID_FUNC_BITOR ); + 2; 0; 0; + 0; + }; + String 2 // Name of Parameter 1 + { + Text [ en-US ] = "Number" ; + }; + String 3 // Description of Parameter 1 + { + Text [ en-US ] = "Positive integer less than 2^48." ; + }; + String 4 // Name of Parameter 2 + { + Text [ en-US ] = "Number" ; + }; + String 5 // Description of Parameter 2 + { + Text [ en-US ] = "Positive integer less than 2^48." ; + }; + }; + Resource SC_OPCODE_BITXOR + { + String 1 // Description + { + Text [ en-US ] = "Bitwise \"exclusive OR\" of two integers."; + }; + ExtraData = + { + 0; + ID_FUNCTION_GRP_MATH; + U2S( HID_FUNC_BITXOR ); + 2; 0; 0; + 0; + }; + String 2 // Name of Parameter 1 + { + Text [ en-US ] = "Number" ; + }; + String 3 // Description of Parameter 1 + { + Text [ en-US ] = "Positive integer less than 2^48." ; + }; + String 4 // Name of Parameter 2 + { + Text [ en-US ] = "Number" ; + }; + String 5 // Description of Parameter 2 + { + Text [ en-US ] = "Positive integer less than 2^48." ; + }; + }; + Resource SC_OPCODE_BITRSHIFT + { + String 1 // Description + { + Text [ en-US ] = "Bitwise right shift of an integer value."; + }; + ExtraData = + { + 0; + ID_FUNCTION_GRP_MATH; + U2S( HID_FUNC_BITRSHIFT ); + 2; 0; 0; + 0; + }; + String 2 // Name of Parameter 1 + { + Text [ en-US ] = "Number" ; + }; + String 3 // Description of Parameter 1 + { + Text [ en-US ] = "The value to be shifted. Positive integer less than 2^48." ; + }; + String 4 // Name of Parameter 2 + { + Text [ en-US ] = "Shift" ; + }; + String 5 // Description of Parameter 2 + { + Text [ en-US ] = "The integer number of bits the value is to be shifted." ; + }; + }; + Resource SC_OPCODE_BITLSHIFT + { + String 1 // Description + { + Text [ en-US ] = "Bitwise left shift of an integer value."; + }; + ExtraData = + { + 0; + ID_FUNCTION_GRP_MATH; + U2S( HID_FUNC_BITLSHIFT ); + 2; 0; 0; + 0; + }; + String 2 // Name of Parameter 1 + { + Text [ en-US ] = "Number" ; + }; + String 3 // Description of Parameter 1 + { + Text [ en-US ] = "The value to be shifted. Positive integer less than 2^48." ; + }; + String 4 // Name of Parameter 2 + { + Text [ en-US ] = "Shift" ; + }; + String 5 // Description of Parameter 2 + { + Text [ en-US ] = "The integer number of bits the value is to be shifted." ; + }; + }; }; #if defined(U2S) diff --git a/sc/util/hidother.src b/sc/util/hidother.src index d575580228bd..b45e5fa5898d 100644 --- a/sc/util/hidother.src +++ b/sc/util/hidother.src @@ -363,6 +363,11 @@ hidspecial HID_FUNC_NUMBERVALUE { HelpID = HID_FUNC_NUMBERVALUE; }; hidspecial HID_FUNC_GAMMA { HelpID = HID_FUNC_GAMMA; }; hidspecial HID_FUNC_CHISQDIST { HelpID = HID_FUNC_CHISQDIST; }; hidspecial HID_FUNC_CHISQINV { HelpID = HID_FUNC_CHISQINV; }; +hidspecial HID_FUNC_BITAND { HelpID = HID_FUNC_BITAND; }; +hidspecial HID_FUNC_BITOR { HelpID = HID_FUNC_BITOR; }; +hidspecial HID_FUNC_BITXOR { HelpID = HID_FUNC_BITXOR; }; +hidspecial HID_FUNC_BITRSHIFT { HelpID = HID_FUNC_BITRSHIFT; }; +hidspecial HID_FUNC_BITLSHIFT { HelpID = HID_FUNC_BITLSHIFT; }; // ... and from Analysis Addin |