Kaydet (Commit) c6b49f90 authored tarafından Wolfgang Pechlaner's avatar Wolfgang Pechlaner Kaydeden (comit) Eike Rathke

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 ;-)
üst 5b80048a
...@@ -392,9 +392,13 @@ ...@@ -392,9 +392,13 @@
#define SC_OPCODE_NUMBERVALUE 392 #define SC_OPCODE_NUMBERVALUE 392
#define SC_OPCODE_CHISQ_DIST 393 #define SC_OPCODE_CHISQ_DIST 393
#define SC_OPCODE_CHISQ_INV 394 #define SC_OPCODE_CHISQ_INV 394
#define SC_OPCODE_STOP_2_PAR 395 #define SC_OPCODE_BITAND 395
#define SC_OPCODE_BITOR 396
#define SC_OPCODE_LAST_OPCODE_ID 394 /* last OpCode */ #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 ***/ /*** Interna ***/
#define SC_OPCODE_INTERNAL_BEGIN 9999 #define SC_OPCODE_INTERNAL_BEGIN 9999
......
...@@ -365,6 +365,12 @@ enum OpCodeEnum ...@@ -365,6 +365,12 @@ enum OpCodeEnum
ocTableOp = SC_OPCODE_TABLE_OP, ocTableOp = SC_OPCODE_TABLE_OP,
ocBetaDist = SC_OPCODE_BETA_DIST, ocBetaDist = SC_OPCODE_BETA_DIST,
ocBetaInv = SC_OPCODE_BETA_INV, 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 // miscellaneous
ocWeek = SC_OPCODE_WEEK, ocWeek = SC_OPCODE_WEEK,
ocGetDayOfWeek = SC_OPCODE_GET_DAY_OF_WEEK, ocGetDayOfWeek = SC_OPCODE_GET_DAY_OF_WEEK,
......
...@@ -344,7 +344,11 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH_ODFF ...@@ -344,7 +344,11 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH_ODFF
String SC_OPCODE_GAMMA { Text = "GAMMA" ; }; String SC_OPCODE_GAMMA { Text = "GAMMA" ; };
String SC_OPCODE_CHISQ_DIST { Text = "CHISQDIST" ; }; String SC_OPCODE_CHISQ_DIST { Text = "CHISQDIST" ; };
String SC_OPCODE_CHISQ_INV { Text = "CHISQINV" ;}; 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. */ /* BEGIN defined ERROR.TYPE() values. */
String SC_OPCODE_ERROR_NULL { Text = "#NULL!" ; }; String SC_OPCODE_ERROR_NULL { Text = "#NULL!" ; };
String SC_OPCODE_ERROR_DIVZERO { Text = "#DIV/0!" ; }; String SC_OPCODE_ERROR_DIVZERO { Text = "#DIV/0!" ; };
...@@ -672,7 +676,11 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH ...@@ -672,7 +676,11 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH
String SC_OPCODE_GAMMA { Text = "GAMMA" ; }; String SC_OPCODE_GAMMA { Text = "GAMMA" ; };
String SC_OPCODE_CHISQ_DIST { Text = "CHISQDIST" ; }; String SC_OPCODE_CHISQ_DIST { Text = "CHISQDIST" ; };
String SC_OPCODE_CHISQ_INV { Text = "CHISQINV" ;}; 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. */ /* BEGIN defined ERROR.TYPE() values. */
String SC_OPCODE_ERROR_NULL { Text = "#NULL!" ; }; String SC_OPCODE_ERROR_NULL { Text = "#NULL!" ; };
String SC_OPCODE_ERROR_DIVZERO { Text = "#DIV/0!" ; }; String SC_OPCODE_ERROR_DIVZERO { Text = "#DIV/0!" ; };
...@@ -1860,6 +1868,26 @@ Resource RID_STRLIST_FUNCTION_NAMES ...@@ -1860,6 +1868,26 @@ Resource RID_STRLIST_FUNCTION_NAMES
{ {
Text [ en-US ] = "CHISQINV" ; 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. */ /* BEGIN defined ERROR.TYPE() values. */
/* ERROR.TYPE( #NULL! ) == 1 */ /* ERROR.TYPE( #NULL! ) == 1 */
String SC_OPCODE_ERROR_NULL String SC_OPCODE_ERROR_NULL
......
...@@ -692,3 +692,8 @@ ...@@ -692,3 +692,8 @@
#define HID_FUNC_UNICODE "SC_HID_FUNC_UNICODE" #define HID_FUNC_UNICODE "SC_HID_FUNC_UNICODE"
#define HID_FUNC_UNICHAR "SC_HID_FUNC_UNICHAR" #define HID_FUNC_UNICHAR "SC_HID_FUNC_UNICHAR"
#define HID_FUNC_NUMBERVALUE "SC_HID_FUNC_NUMBERVALUE" #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"
...@@ -1764,6 +1764,11 @@ void Test::testFunctionLists() ...@@ -1764,6 +1764,11 @@ void Test::testFunctionLists()
"ATAN", "ATAN",
"ATAN2", "ATAN2",
"ATANH", "ATANH",
"BITAND",
"BITLSHIFT",
"BITOR",
"BITRSHIFT",
"BITXOR",
"CEILING", "CEILING",
"COMBIN", "COMBIN",
"COMBINA", "COMBINA",
......
...@@ -557,6 +557,11 @@ void ScColRowNameAuto(); ...@@ -557,6 +557,11 @@ void ScColRowNameAuto();
void ScGetPivotData(); void ScGetPivotData();
void ScHyperLink(); void ScHyperLink();
void ScBahtText(); void ScBahtText();
void ScBitAnd();
void ScBitOr();
void ScBitXor();
void ScBitRshift();
void ScBitLshift();
void ScTTT(); void ScTTT();
//----------------Funktionen in interpr2.cxx--------------- //----------------Funktionen in interpr2.cxx---------------
......
...@@ -77,6 +77,8 @@ ...@@ -77,6 +77,8 @@
#define SC_DOUBLE_MAXVALUE 1.7e307 #define SC_DOUBLE_MAXVALUE 1.7e307
static const sal_uInt64 n2power48 = 281474976710656; // 2^48
IMPL_FIXEDMEMPOOL_NEWDEL( ScTokenStack, 8, 4 ) IMPL_FIXEDMEMPOOL_NEWDEL( ScTokenStack, 8, 4 )
IMPL_FIXEDMEMPOOL_NEWDEL( ScInterpreter, 32, 16 ) IMPL_FIXEDMEMPOOL_NEWDEL( ScInterpreter, 32, 16 )
...@@ -1449,6 +1451,107 @@ void ScInterpreter::ScNot() ...@@ -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() void ScInterpreter::ScPi()
{ {
RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScPi" ); RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScPi" );
......
...@@ -4063,6 +4063,11 @@ StackVar ScInterpreter::Interpret() ...@@ -4063,6 +4063,11 @@ StackVar ScInterpreter::Interpret()
case ocAsc : ScAsc(); break; case ocAsc : ScAsc(); break;
case ocUnicode : ScUnicode(); break; case ocUnicode : ScUnicode(); break;
case ocUnichar : ScUnichar(); 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 ocTTT : ScTTT(); break;
case ocNone : nFuncFmtType = NUMBERFORMAT_UNDEFINED; break; case ocNone : nFuncFmtType = NUMBERFORMAT_UNDEFINED; break;
default : PushError( errUnknownOpCode); break; default : PushError( errUnknownOpCode); break;
......
...@@ -9037,6 +9037,162 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2 ...@@ -9037,6 +9037,162 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2
Text [ en-US ] = "Defines the character used as the decimal point." ; 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) #if defined(U2S)
......
...@@ -363,6 +363,11 @@ hidspecial HID_FUNC_NUMBERVALUE { HelpID = HID_FUNC_NUMBERVALUE; }; ...@@ -363,6 +363,11 @@ hidspecial HID_FUNC_NUMBERVALUE { HelpID = HID_FUNC_NUMBERVALUE; };
hidspecial HID_FUNC_GAMMA { HelpID = HID_FUNC_GAMMA; }; hidspecial HID_FUNC_GAMMA { HelpID = HID_FUNC_GAMMA; };
hidspecial HID_FUNC_CHISQDIST { HelpID = HID_FUNC_CHISQDIST; }; hidspecial HID_FUNC_CHISQDIST { HelpID = HID_FUNC_CHISQDIST; };
hidspecial HID_FUNC_CHISQINV { HelpID = HID_FUNC_CHISQINV; }; 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 // ... and from Analysis Addin
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment