You've already forked lazarus-ccr
fpspreadsheet: Support cell ranges in calculation of rpn formulas. Tune fpfunc unit. Update test cases.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3272 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -10,8 +10,8 @@
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="test_formula_func"/>
|
||||
<IsVisibleTab Value="True"/>
|
||||
<TopLine Value="65"/>
|
||||
<CursorPos X="47" Y="97"/>
|
||||
<TopLine Value="33"/>
|
||||
<CursorPos X="14" Y="47"/>
|
||||
<UsageCount Value="20"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit0>
|
||||
@ -28,8 +28,8 @@
|
||||
<Filename Value="..\..\fpsfunc.pas"/>
|
||||
<UnitName Value="fpsfunc"/>
|
||||
<EditorIndex Value="2"/>
|
||||
<TopLine Value="24"/>
|
||||
<CursorPos Y="50"/>
|
||||
<TopLine Value="1594"/>
|
||||
<CursorPos X="35" Y="1603"/>
|
||||
<UsageCount Value="10"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit2>
|
||||
@ -45,124 +45,124 @@
|
||||
</Units>
|
||||
<JumpHistory Count="30" HistoryIndex="29">
|
||||
<Position1>
|
||||
<Filename Value="..\..\fpspreadsheet.pas"/>
|
||||
<Caret Line="2988" TopLine="2960"/>
|
||||
<Filename Value="..\..\fpsutils.pas"/>
|
||||
<Caret Line="856" TopLine="836"/>
|
||||
</Position1>
|
||||
<Position2>
|
||||
<Filename Value="..\..\fpspreadsheet.pas"/>
|
||||
<Caret Line="2987" TopLine="2960"/>
|
||||
<Filename Value="..\..\fpsutils.pas"/>
|
||||
<Caret Line="858" TopLine="836"/>
|
||||
</Position2>
|
||||
<Position3>
|
||||
<Filename Value="..\..\fpsutils.pas"/>
|
||||
<Caret Line="853" TopLine="836"/>
|
||||
<Caret Line="860" TopLine="836"/>
|
||||
</Position3>
|
||||
<Position4>
|
||||
<Filename Value="..\..\fpsutils.pas"/>
|
||||
<Caret Line="854" TopLine="836"/>
|
||||
<Caret Line="861" TopLine="836"/>
|
||||
</Position4>
|
||||
<Position5>
|
||||
<Filename Value="..\..\fpsutils.pas"/>
|
||||
<Caret Line="855" TopLine="836"/>
|
||||
<Caret Line="863" TopLine="836"/>
|
||||
</Position5>
|
||||
<Position6>
|
||||
<Filename Value="..\..\fpsutils.pas"/>
|
||||
<Caret Line="856" TopLine="836"/>
|
||||
<Caret Line="864" TopLine="836"/>
|
||||
</Position6>
|
||||
<Position7>
|
||||
<Filename Value="..\..\fpsutils.pas"/>
|
||||
<Caret Line="858" TopLine="836"/>
|
||||
<Caret Line="865" TopLine="836"/>
|
||||
</Position7>
|
||||
<Position8>
|
||||
<Filename Value="..\..\fpsutils.pas"/>
|
||||
<Caret Line="860" TopLine="836"/>
|
||||
<Caret Line="867" TopLine="837"/>
|
||||
</Position8>
|
||||
<Position9>
|
||||
<Filename Value="..\..\fpsutils.pas"/>
|
||||
<Caret Line="861" TopLine="836"/>
|
||||
<Caret Line="875" TopLine="857"/>
|
||||
</Position9>
|
||||
<Position10>
|
||||
<Filename Value="..\..\fpsutils.pas"/>
|
||||
<Caret Line="863" TopLine="836"/>
|
||||
<Caret Line="876" TopLine="857"/>
|
||||
</Position10>
|
||||
<Position11>
|
||||
<Filename Value="..\..\fpsutils.pas"/>
|
||||
<Caret Line="864" TopLine="836"/>
|
||||
<Caret Line="879" TopLine="857"/>
|
||||
</Position11>
|
||||
<Position12>
|
||||
<Filename Value="..\..\fpsutils.pas"/>
|
||||
<Caret Line="865" TopLine="836"/>
|
||||
<Caret Line="876" TopLine="857"/>
|
||||
</Position12>
|
||||
<Position13>
|
||||
<Filename Value="..\..\fpsutils.pas"/>
|
||||
<Caret Line="867" TopLine="837"/>
|
||||
<Caret Line="879" TopLine="857"/>
|
||||
</Position13>
|
||||
<Position14>
|
||||
<Filename Value="..\..\fpsutils.pas"/>
|
||||
<Caret Line="875" TopLine="857"/>
|
||||
<Caret Line="877" TopLine="857"/>
|
||||
</Position14>
|
||||
<Position15>
|
||||
<Filename Value="..\..\fpsutils.pas"/>
|
||||
<Caret Line="876" TopLine="857"/>
|
||||
<Caret Line="879" TopLine="857"/>
|
||||
</Position15>
|
||||
<Position16>
|
||||
<Filename Value="..\..\fpsutils.pas"/>
|
||||
<Caret Line="879" TopLine="857"/>
|
||||
<Caret Line="878" TopLine="857"/>
|
||||
</Position16>
|
||||
<Position17>
|
||||
<Filename Value="..\..\fpsutils.pas"/>
|
||||
<Caret Line="876" TopLine="857"/>
|
||||
<Caret Line="879" TopLine="857"/>
|
||||
</Position17>
|
||||
<Position18>
|
||||
<Filename Value="..\..\fpsutils.pas"/>
|
||||
<Caret Line="879" TopLine="857"/>
|
||||
<Caret Line="878" TopLine="857"/>
|
||||
</Position18>
|
||||
<Position19>
|
||||
<Filename Value="..\..\fpsutils.pas"/>
|
||||
<Caret Line="877" TopLine="857"/>
|
||||
<Caret Line="879" TopLine="857"/>
|
||||
</Position19>
|
||||
<Position20>
|
||||
<Filename Value="..\..\fpsutils.pas"/>
|
||||
<Caret Line="879" TopLine="857"/>
|
||||
<Caret Line="876" TopLine="857"/>
|
||||
</Position20>
|
||||
<Position21>
|
||||
<Filename Value="..\..\fpsutils.pas"/>
|
||||
<Caret Line="878" TopLine="857"/>
|
||||
<Caret Line="879" TopLine="857"/>
|
||||
</Position21>
|
||||
<Position22>
|
||||
<Filename Value="..\..\fpsutils.pas"/>
|
||||
<Caret Line="879" TopLine="857"/>
|
||||
<Caret Line="894" TopLine="876"/>
|
||||
</Position22>
|
||||
<Position23>
|
||||
<Filename Value="..\..\fpsutils.pas"/>
|
||||
<Caret Line="878" TopLine="857"/>
|
||||
</Position23>
|
||||
<Position24>
|
||||
<Filename Value="..\..\fpsutils.pas"/>
|
||||
<Caret Line="879" TopLine="857"/>
|
||||
</Position24>
|
||||
<Position25>
|
||||
<Filename Value="..\..\fpsutils.pas"/>
|
||||
<Caret Line="876" TopLine="857"/>
|
||||
</Position25>
|
||||
<Position26>
|
||||
<Filename Value="..\..\fpsutils.pas"/>
|
||||
<Caret Line="879" TopLine="857"/>
|
||||
</Position26>
|
||||
<Position27>
|
||||
<Filename Value="..\..\fpsutils.pas"/>
|
||||
<Caret Line="894" TopLine="876"/>
|
||||
</Position27>
|
||||
<Position28>
|
||||
<Filename Value="..\..\fpspreadsheet.pas"/>
|
||||
<Caret Line="2997" TopLine="2966"/>
|
||||
</Position28>
|
||||
<Position29>
|
||||
</Position23>
|
||||
<Position24>
|
||||
<Filename Value="..\..\fpspreadsheet.pas"/>
|
||||
<Caret Line="2998" TopLine="2967"/>
|
||||
</Position29>
|
||||
<Position30>
|
||||
</Position24>
|
||||
<Position25>
|
||||
<Filename Value="..\..\fpspreadsheet.pas"/>
|
||||
<Caret Line="2961" TopLine="2942"/>
|
||||
</Position25>
|
||||
<Position26>
|
||||
<Filename Value="..\..\fpsfunc.pas"/>
|
||||
<Caret Line="50" TopLine="24"/>
|
||||
</Position26>
|
||||
<Position27>
|
||||
<Filename Value="..\..\fpsfunc.pas"/>
|
||||
<Caret Line="1607" Column="52" TopLine="1591"/>
|
||||
</Position27>
|
||||
<Position28>
|
||||
<Filename Value="..\..\fpsfunc.pas"/>
|
||||
<Caret Line="1606" Column="16" TopLine="1592"/>
|
||||
</Position28>
|
||||
<Position29>
|
||||
<Filename Value="..\..\fpsfunc.pas"/>
|
||||
<Caret Line="1610" Column="8" TopLine="1593"/>
|
||||
</Position29>
|
||||
<Position30>
|
||||
<Filename Value="test_formula_func.pas"/>
|
||||
<Caret Line="61" Column="24" TopLine="39"/>
|
||||
</Position30>
|
||||
</JumpHistory>
|
||||
</ProjectSession>
|
||||
|
@ -44,24 +44,20 @@ end;
|
||||
|
||||
function fpsFV(Args: TsArgumentStack; NumArgs: Integer): TsArgument;
|
||||
var
|
||||
arg_interestRate, arg_numberPayments, arg_Payment, arg_PV, arg_paymentType: TsArgument;
|
||||
data: TsArgNumberArray;
|
||||
begin
|
||||
// Pop the argument off the stack.
|
||||
// Note: they come off in the reverse order they were pushed!
|
||||
arg_paymentType := Args.Pop;
|
||||
arg_PV := Args.Pop;
|
||||
arg_Payment := Args.Pop;
|
||||
arg_numberPayments := Args.Pop;
|
||||
arg_interestRate := Args.Pop;
|
||||
|
||||
// Call our FV function with the NumberValues of the arguments.
|
||||
Result := CreateNumber(FV(
|
||||
arg_interestRate.NumberValue,
|
||||
arg_numberPayments.NumberValue,
|
||||
arg_Payment.NumberValue,
|
||||
arg_PV.NumberValue,
|
||||
round(arg_paymentType.NumberValue)
|
||||
));
|
||||
// Pop the argument off the stack. This can be done by means of PopNumberValues
|
||||
// which brings the values back into the right order and reports an error
|
||||
// in case of non-numerical values.
|
||||
if Args.PopNumberValues(NumArgs, false, data, Result) then
|
||||
// Call our FV function with the NumberValues of the arguments.
|
||||
Result := CreateNumber(FV(
|
||||
data[0], // interest rate
|
||||
data[1], // number of payments
|
||||
data[2], // payment
|
||||
data[3], // present value
|
||||
round(data[4]) // payment type
|
||||
));
|
||||
end;
|
||||
|
||||
const
|
||||
@ -119,6 +115,7 @@ begin
|
||||
nil))))))));
|
||||
|
||||
workbook.WriteToFile('test_fv.xls', sfExcel8, true);
|
||||
|
||||
finally
|
||||
workbook.Free;
|
||||
end;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1496,6 +1496,7 @@ var
|
||||
val: TsArgument;
|
||||
fe: TsFormulaElement;
|
||||
cell: PCell;
|
||||
r,c: Cardinal;
|
||||
begin
|
||||
if (Length(ACell^.RPNFormulaValue) = 0) or
|
||||
(ACell^.ContentType = cctError)
|
||||
@ -1516,9 +1517,21 @@ begin
|
||||
csNotCalculated: CalcRPNFormula(cell);
|
||||
csCalculating : raise Exception.Create(lpCircularReference);
|
||||
end;
|
||||
args.PushCell(cell);
|
||||
args.PushCell(cell, self);
|
||||
end;
|
||||
fekCellRange:
|
||||
begin
|
||||
for r := fe.Row to fe.Row2 do
|
||||
for c := fe.Col to fe.Col2 do begin
|
||||
cell := FindCell(r, c);
|
||||
if cell <> nil then
|
||||
case cell^.CalcState of
|
||||
csNotCalculated: CalcRPNFormula(cell);
|
||||
csCalculating : raise Exception.Create(lpCircularReference);
|
||||
end;
|
||||
end;
|
||||
args.PushCellRange(fe.Row, fe.Col, fe.Row2, fe.Col2, self);
|
||||
end;
|
||||
fekCellRange: ;
|
||||
fekNum:
|
||||
args.PushNumber(fe.DoubleValue);
|
||||
fekInteger:
|
||||
|
@ -6,6 +6,7 @@
|
||||
{------------------------------------------------------------------------------}
|
||||
// Addition
|
||||
Row := 0;
|
||||
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=1+1');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNNumber(1.0,
|
||||
@ -13,6 +14,9 @@
|
||||
RPNFunc(fekAdd, nil)))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(1.0+1.0); // B1 = 2
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// DO NOT CHANGE THIS FORMULA - ITS RESULT (2) IS HARD-CODED IN OTHER TESTS !
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
// Subtraction
|
||||
inc(Row);
|
||||
@ -22,7 +26,10 @@
|
||||
RPNNumber(10,
|
||||
RPNFunc(fekSub, nil)))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(1-10); // B2 = -9
|
||||
sollValues[Row] := CreateNumber(1-10); // B2 = -9
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// DO NOT CHANGE THIS FORMULA - ITS RESULT (-9) IS HARD-CODED IN OTHER TESTS !
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
// Add cell values - relative addresses
|
||||
inc(Row);
|
||||
@ -78,6 +85,16 @@
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(10*(-3));
|
||||
|
||||
// Multiplication of cell values
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=B1*B2');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNCellValue('B1',
|
||||
RPNCellValue('B2',
|
||||
RPNFunc(fekMul, nil)))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(2*(-9));
|
||||
|
||||
// Division
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=10/200');
|
||||
@ -98,6 +115,16 @@
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateError(errDivideByZero);
|
||||
|
||||
// Division of cell values
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=B1/B2');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNCellValue('B1',
|
||||
RPNcellValue('B2',
|
||||
RPNFunc(fekDiv, nil)))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(2/(-9));
|
||||
|
||||
// Percentage
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=10%');
|
||||
@ -107,9 +134,18 @@
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(10*0.01);
|
||||
|
||||
// Percentage of cell value
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=B1%');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNCellValue('B1',
|
||||
RPNFunc(fekPercent, nil))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(2*0.01);
|
||||
|
||||
// Power
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=power(2.0, 0.5)');
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=power(2.0,0.5)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNNumber(2.0,
|
||||
RPNNumber(0.5,
|
||||
@ -117,6 +153,16 @@
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(power(2, 0.5));
|
||||
|
||||
// Power of cell values
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=power(B1,B2)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNCellValue('B1',
|
||||
RPNCellValue('B2',
|
||||
RPNFunc(fekPower, nil)))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(power(2, -9));
|
||||
|
||||
{$IFDEF ENABLE_CALC_RPN_EXCEPTIONS}
|
||||
// Power: Error case "power( (negative number), (fractional number) )"
|
||||
inc(Row);
|
||||
@ -139,6 +185,15 @@
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(1);
|
||||
|
||||
// Unary minus of cell value
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=-B1');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNCellValue('B1',
|
||||
RPNFunc(fekUMinus, nil))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(-(2));
|
||||
|
||||
// Unary plus
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=+(-1)');
|
||||
@ -149,6 +204,15 @@
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(-1);
|
||||
|
||||
// Unary plus of cell value
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=+(B2)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNCellvalue('B2',
|
||||
RPNFunc(fekUPlus, nil))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(+(-9));
|
||||
|
||||
// String result
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '="Hallo"');
|
||||
@ -593,7 +657,7 @@
|
||||
RPNMissingArg(
|
||||
RPNFunc(fekLOG, 2, nil)))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(logn(10, 0.1));
|
||||
sollValues[Row] := CreateError(errOverflow);
|
||||
|
||||
// LOG - valid result (1 argument)
|
||||
inc(Row);
|
||||
@ -624,6 +688,15 @@
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateError(errOverflow);
|
||||
|
||||
// LOG of cell
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=log(B1)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNCellValue('B1',
|
||||
RPNFunc(fekLOG, 1, nil))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(logn(10, 2));
|
||||
|
||||
// PI
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=pi()');
|
||||
@ -641,6 +714,15 @@
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(degtorad(60));
|
||||
|
||||
// RADIANS of cell value
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=radians(B1)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNCellValue('B1',
|
||||
RPNFunc(fekRADIANS, nil))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(degtorad(2));
|
||||
|
||||
// RAND
|
||||
// Test omitted because we cannot enforce getting the same random number back
|
||||
// when we are reading the file.
|
||||
@ -664,6 +746,15 @@
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(sign(-0.1));
|
||||
|
||||
// SIGN of cell value
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=sign(B1)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNCellValue('B1',
|
||||
RPNFunc(fekSIGN, nil))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(sign(2));
|
||||
|
||||
// SIN
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=sin(0.1)');
|
||||
@ -673,6 +764,15 @@
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(sin(0.1));
|
||||
|
||||
// SIN of cell value
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=sin(B1)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNCellValue('B1',
|
||||
RPNFunc(fekSIN, nil))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(sin(2));
|
||||
|
||||
// SINH
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=sinh(0.1)');
|
||||
@ -682,6 +782,15 @@
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(sinh(0.1));
|
||||
|
||||
// SINH of cell value
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=sinh(B1)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNCellValue('B1',
|
||||
RPNFunc(fekSINH, nil))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(sinh(2));
|
||||
|
||||
// SQRT - valid result
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=sqrt(0.1)');
|
||||
@ -700,6 +809,15 @@
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateError(errOverflow);
|
||||
|
||||
// SQRT of cell value
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=sqrt(B1)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNCellvalue('B1',
|
||||
RPNFunc(fekSQRT, nil))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(sqrt(2));
|
||||
|
||||
// TAN - valid result
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=tan(0.1)');
|
||||
@ -712,6 +830,15 @@
|
||||
// TAN - error (argument = pi/2)
|
||||
// This test is omitted because it is difficult to exactly hit pi/2.
|
||||
|
||||
// TAN of cell value
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=tan(B1)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNCellValue('B1',
|
||||
RPNFunc(fekTAN, nil))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(tan(2));
|
||||
|
||||
// TANH
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=tanh(0.1)');
|
||||
@ -721,6 +848,15 @@
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(tanh(0.1));
|
||||
|
||||
// TANH of cell value
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=tanh(B1)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNCellValue('B1',
|
||||
RPNFunc(fekTANH, nil))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(tanh(2));
|
||||
|
||||
|
||||
{------------------------------------------------------------------------------}
|
||||
{ Date/time functions }
|
||||
@ -975,7 +1111,16 @@
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(mean([1.0, 1.1, 1.2, 0.9, 0.8]));
|
||||
|
||||
// COUNT (no missing values)
|
||||
// AVERAGE of cell block
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=AVERAGE(B1:B2)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNCellRange('B1:B2',
|
||||
RPNFunc(fekAVERAGE, 1, nil))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(mean([2.0, -9.0]));
|
||||
|
||||
// COUNT
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=COUNT(1, 1.1, 1.2, 0.9, 0.8)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
@ -988,20 +1133,34 @@
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(5);
|
||||
|
||||
// COUNT (with missing values)
|
||||
// COUNT of cell range (no empty cells)
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=COUNT(1, , 1.2, , 0.8)');
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=COUNT(B1:B2)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNNumber(1.0,
|
||||
RPNMissingArg(
|
||||
RPNNumber(1.2,
|
||||
RPNMissingArg(
|
||||
RPNNumber(0.8,
|
||||
RPNFunc(fekCOUNT, 5, nil))))))));
|
||||
RPNCellrange('B1:B2',
|
||||
RPNFunc(fekCOUNT, 1, nil))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(3);
|
||||
sollValues[Row] := CreateNumber(2);
|
||||
|
||||
// MAX
|
||||
// COUNT of cell range (no empty cells, but with non-numeric cells)
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=COUNT(A1:B2)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNCellrange('A1:B2',
|
||||
RPNFunc(fekCOUNT, 1, nil))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(2);
|
||||
|
||||
// COUNT of cell range (with empty cells)
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=COUNT(B1:C2)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNCellrange('B1:C2',
|
||||
RPNFunc(fekCOUNT, 1, nil))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(2);
|
||||
|
||||
// MAX
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=MAX(1, 1.1, 1.2, 0.9, 0.8)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
@ -1014,20 +1173,25 @@
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(MaxValue([1.0, 1.1, 1.2, 0.9, 0.8]));
|
||||
|
||||
// MAX (with missing values)
|
||||
// MAX of cell range (no empty cells)
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=MAX(1, , , 0.9, 0.8)');
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=MAX(B1:B2)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNNumber(1.0,
|
||||
RPNMissingArg(
|
||||
RPNMissingArg(
|
||||
RPNNumber(0.9,
|
||||
RPNNumber(0.8,
|
||||
RPNFunc(fekMAX, 5, nil))))))));
|
||||
RPNCellRange('B1:B2',
|
||||
RPNFunc(fekMAX, 1, nil))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(MaxValue([1.0, {1.1, 1.2,} 0.9, 0.8]));
|
||||
sollValues[Row] := CreateNumber(MaxValue([2.0, -9.0]));
|
||||
|
||||
// MIN
|
||||
// MAX of cell range (incl empty cells)
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=MAX(B1:C2)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNCellRange('B1:C2',
|
||||
RPNFunc(fekMAX, 1, nil))));
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := CreateNumber(MaxValue([2.0, -9.0]));
|
||||
|
||||
// MIN
|
||||
inc(Row);
|
||||
MyWorksheet.WriteUTF8Text(Row, 0, '=MIN(1, 1.1, 1.2, 0.9, 0.8)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
|
Reference in New Issue
Block a user