summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWolfgang Pechlaner <libo@pechlaner.at>2011-09-04 14:40:25 +0200
committerEike Rathke <erack@erack.de>2011-09-07 12:27:27 +0200
commitc6b49f9098fb6c9816202e8d465c342788736af5 (patch)
treed1074becd133921d5dc77cf3afe9f1ac74516c67
parent5b80048a1ef119db569f9e9a259e94e773201b1f (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-xformula/inc/formula/compiler.hrc10
-rw-r--r--formula/inc/formula/opcode.hxx6
-rw-r--r--formula/source/core/resource/core_resource.src32
-rw-r--r--sc/inc/helpids.h5
-rw-r--r--sc/qa/unit/ucalc.cxx5
-rw-r--r--sc/source/core/inc/interpre.hxx5
-rw-r--r--sc/source/core/tool/interpr1.cxx103
-rw-r--r--sc/source/core/tool/interpr4.cxx5
-rw-r--r--sc/source/ui/src/scfuncs.src156
-rw-r--r--sc/util/hidother.src5
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