summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--formula/inc/core_resource.hrc12
-rw-r--r--include/formula/compiler.hxx6
-rw-r--r--include/formula/opcode.hxx4
-rw-r--r--sc/inc/helpids.h2
-rw-r--r--sc/inc/scfuncs.hrc16
-rw-r--r--sc/qa/extras/scfunctionlistobj.cxx2
-rw-r--r--sc/qa/unit/ucalc.cxx2
-rw-r--r--sc/source/core/data/funcdesc.cxx4
-rw-r--r--sc/source/core/inc/interpre.hxx3
-rw-r--r--sc/source/core/tool/interpr1.cxx42
-rw-r--r--sc/source/core/tool/interpr4.cxx2
-rw-r--r--sc/source/core/tool/parclass.cxx1
-rw-r--r--sc/source/filter/excel/xlformula.cxx4
-rw-r--r--sc/source/filter/oox/formulabase.cxx4
14 files changed, 93 insertions, 11 deletions
diff --git a/formula/inc/core_resource.hrc b/formula/inc/core_resource.hrc
index 2ad8d3cf5a9e..cf1cca33373f 100644
--- a/formula/inc/core_resource.hrc
+++ b/formula/inc/core_resource.hrc
@@ -467,6 +467,8 @@ const std::pair<const char*, int> RID_STRLIST_FUNCTION_NAMES_ENGLISH_ODFF[] =
{ "ORG.LIBREOFFICE.ROUNDSIG" , SC_OPCODE_ROUNDSIG },
{ "ORG.LIBREOFFICE.REGEX" , SC_OPCODE_REGEX },
{ "ORG.LIBREOFFICE.FOURIER", SC_OPCODE_FOURIER },
+ { "ORG.LIBREOFFICE.RAND.NV" , SC_OPCODE_RANDOM_NV },
+ { "ORG.LIBREOFFICE.RANDBETWEEN.NV" , SC_OPCODE_RANDBETWEEN_NV },
{ nullptr, -1 }
};
@@ -911,6 +913,8 @@ const std::pair<const char*, int> RID_STRLIST_FUNCTION_NAMES_ENGLISH_OOXML[] =
{ "_xlfn.ORG.LIBREOFFICE.ROUNDSIG" , SC_OPCODE_ROUNDSIG },
{ "_xlfn.ORG.LIBREOFFICE.REGEX" , SC_OPCODE_REGEX },
{ "_xlfn.ORG.LIBREOFFICE.FOURIER", SC_OPCODE_FOURIER },
+ { "_xlfn.ORG.LIBREOFFICE.RAND.NV" , SC_OPCODE_RANDOM_NV },
+ { "_xlfn.ORG.LIBREOFFICE.RANDBETWEEN.NV" , SC_OPCODE_RANDBETWEEN_NV },
{ nullptr, -1 }
};
@@ -1360,6 +1364,8 @@ const std::pair<const char*, int> RID_STRLIST_FUNCTION_NAMES_ENGLISH_PODF[] =
{ "ROUNDSIG" , SC_OPCODE_ROUNDSIG },
{ "REGEX" , SC_OPCODE_REGEX },
{ "FOURIER", SC_OPCODE_FOURIER },
+ { "RAND.NV" , SC_OPCODE_RANDOM_NV },
+ { "RANDBETWEEN.NV" , SC_OPCODE_RANDBETWEEN_NV },
{ nullptr, -1 }
};
@@ -1808,6 +1814,8 @@ const std::pair<const char*, int> RID_STRLIST_FUNCTION_NAMES_ENGLISH_API[] =
{ "ROUNDSIG" , SC_OPCODE_ROUNDSIG },
{ "REGEX" , SC_OPCODE_REGEX },
{ "FOURIER", SC_OPCODE_FOURIER },
+ { "RAND.NV" , SC_OPCODE_RANDOM_NV },
+ { "RANDBETWEEN.NV" , SC_OPCODE_RANDBETWEEN_NV },
{ nullptr, -1 }
};
@@ -2255,6 +2263,8 @@ const std::pair<const char*, int> RID_STRLIST_FUNCTION_NAMES_ENGLISH[] =
{ "ROUNDSIG" , SC_OPCODE_ROUNDSIG },
{ "REGEX" , SC_OPCODE_REGEX },
{ "FOURIER", SC_OPCODE_FOURIER },
+ { "RAND.NV" , SC_OPCODE_RANDOM_NV },
+ { "RANDBETWEEN.NV" , SC_OPCODE_RANDBETWEEN_NV },
{ nullptr, -1 }
};
@@ -2699,6 +2709,8 @@ const std::pair<const char*, int> RID_STRLIST_FUNCTION_NAMES[] =
{ NC_("RID_STRLIST_FUNCTION_NAMES", "SEARCHB") , SC_OPCODE_SEARCHB },
{ NC_("RID_STRLIST_FUNCTION_NAMES", "REGEX") , SC_OPCODE_REGEX },
{ NC_("RID_STRLIST_FUNCTION_NAMES", "FOURIER"), SC_OPCODE_FOURIER },
+ { NC_("RID_STRLIST_FUNCTION_NAMES", "RAND.NV"), SC_OPCODE_RANDOM_NV },
+ { NC_("RID_STRLIST_FUNCTION_NAMES", "RANDBETWEEN.NV"), SC_OPCODE_RANDBETWEEN_NV },
{ nullptr, -1 }
};
diff --git a/include/formula/compiler.hxx b/include/formula/compiler.hxx
index c5e5cfdf0da2..baf3e23f6161 100644
--- a/include/formula/compiler.hxx
+++ b/include/formula/compiler.hxx
@@ -112,7 +112,8 @@
#define SC_OPCODE_GET_ACT_TIME 80
#define SC_OPCODE_NO_VALUE 81
#define SC_OPCODE_CURRENT 82
-#define SC_OPCODE_STOP_NO_PAR 83
+#define SC_OPCODE_RANDOM_NV 83
+#define SC_OPCODE_STOP_NO_PAR 84
/*** Functions with one parameter ***/
#define SC_OPCODE_START_1_PAR 90
@@ -507,7 +508,8 @@
#define SC_OPCODE_SEARCHB 496
#define SC_OPCODE_REGEX 497
#define SC_OPCODE_FOURIER 498
-#define SC_OPCODE_STOP_2_PAR 499 /* last function with two or more parameters' OpCode + 1 */
+#define SC_OPCODE_RANDBETWEEN_NV 499
+#define SC_OPCODE_STOP_2_PAR 500 /* last function with two or more parameters' OpCode + 1 */
#define SC_OPCODE_STOP_FUNCTION SC_OPCODE_STOP_2_PAR /* last function's OpCode + 1 */
#define SC_OPCODE_LAST_OPCODE_ID (SC_OPCODE_STOP_FUNCTION - 1) /* last OpCode */
diff --git a/include/formula/opcode.hxx b/include/formula/opcode.hxx
index b969a0047007..3123e8f3fa38 100644
--- a/include/formula/opcode.hxx
+++ b/include/formula/opcode.hxx
@@ -106,6 +106,7 @@ enum OpCode : sal_uInt16
ocGetActTime = SC_OPCODE_GET_ACT_TIME,
ocNotAvail = SC_OPCODE_NO_VALUE,
ocCurrent = SC_OPCODE_CURRENT,
+ ocRandomNV = SC_OPCODE_RANDOM_NV,
// Functions with one parameter
ocNot = SC_OPCODE_NOT,
ocNeg = SC_OPCODE_NEG,
@@ -501,6 +502,7 @@ enum OpCode : sal_uInt16
ocErfc_MS = SC_OPCODE_ERFC_MS,
ocEncodeURL = SC_OPCODE_ENCODEURL,
ocFourier = SC_OPCODE_FOURIER,
+ ocRandbetweenNV = SC_OPCODE_RANDBETWEEN_NV,
// internal stuff
ocInternalBegin = SC_OPCODE_INTERNAL_BEGIN,
ocTTT = SC_OPCODE_TTT,
@@ -586,6 +588,7 @@ inline std::string OpCodeEnumToString(OpCode eCode)
case ocNegSub: return "NegSub";
case ocPi: return "Pi";
case ocRandom: return "Random";
+ case ocRandomNV: return "RandomNV";
case ocTrue: return "True";
case ocFalse: return "False";
case ocGetActDate: return "GetActDate";
@@ -974,6 +977,7 @@ inline std::string OpCodeEnumToString(OpCode eCode)
case ocErfc_MS: return "Erfc_MS";
case ocEncodeURL: return "EncodeURL";
case ocFourier: return "Fourier";
+ case ocRandbetweenNV: return "RandbetweenNV";
case ocTTT: return "TTT";
case ocDebugVar: return "DebugVar";
case ocDataToken1: return "DataToken1";
diff --git a/sc/inc/helpids.h b/sc/inc/helpids.h
index d6616f106784..f9c30fc615a0 100644
--- a/sc/inc/helpids.h
+++ b/sc/inc/helpids.h
@@ -579,6 +579,8 @@
#define HID_FUNC_SEARCHB "SC_HID_FUNC_SEARCHB"
#define HID_FUNC_REGEX "SC_HID_FUNC_REGEX"
#define HID_FUNC_FOURIER "SC_HID_FUNC_FOURIER"
+#define HID_FUNC_RAND_NV "SC_HID_FUNC_RAND_NV"
+#define HID_FUNC_RANDBETWEEN_NV "SC_HID_FUNC_RANDBETWEEN_NV"
#endif
diff --git a/sc/inc/scfuncs.hrc b/sc/inc/scfuncs.hrc
index 77031c5a5ac8..9a96b3d9975c 100644
--- a/sc/inc/scfuncs.hrc
+++ b/sc/inc/scfuncs.hrc
@@ -4134,6 +4134,22 @@ const char* SC_OPCODE_FOURIER_ARY[] =
NC_("SC_OPCODE_FOURIER", "In case of Polar=TRUE, the frequency components below this magnitude are clipped out (default 0.0).")
};
+// -=*# Resource for function RAND.NV #*=-
+const char* SC_OPCODE_RANDOM_NV_ARY[] =
+{
+ NC_("SC_OPCODE_RANDOM_NV", "Returns a random number between 0 and 1, non-volatile.")
+};
+
+// -=*# Resource for function RANDBETWEEN.NV #*=-
+const char* SC_OPCODE_RANDBETWEEN_NV_ARY[] =
+{
+ NC_("SC_OPCODE_RANDBETWEEN_NV", "Returns a random integer between the numbers you specify, non-volatile."),
+ NC_("SC_OPCODE_RANDBETWEEN_NV", "Bottom"),
+ NC_("SC_OPCODE_RANDBETWEEN_NV", "The smallest integer returned."),
+ NC_("SC_OPCODE_RANDBETWEEN_NV", "Top"),
+ NC_("SC_OPCODE_RANDBETWEEN_NV", "The largest integer returned.")
+};
+
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/qa/extras/scfunctionlistobj.cxx b/sc/qa/extras/scfunctionlistobj.cxx
index cf8c962bfb06..385ea7d8962a 100644
--- a/sc/qa/extras/scfunctionlistobj.cxx
+++ b/sc/qa/extras/scfunctionlistobj.cxx
@@ -82,7 +82,7 @@ private:
ScFunctionListObj::ScFunctionListObj()
: CalcUnoApiTest("/sc/qa/extras/testdocuments")
, XElementAccess(cppu::UnoType<uno::Sequence<beans::PropertyValue>>::get())
- , XIndexAccess(393)
+ , XIndexAccess(395)
, XNameAccess("IF")
, XServiceInfo("stardiv.StarCalc.ScFunctionListObj", "com.sun.star.sheet.FunctionDescriptions")
{
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 964247b9fe7f..0bc11aaeeaae 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -2405,6 +2405,8 @@ void Test::testFunctionLists()
"PRODUCT",
"RADIANS",
"RAND",
+ "RAND.NV",
+ "RANDBETWEEN.NV",
"RAWSUBTRACT",
"ROUND",
"ROUNDDOWN",
diff --git a/sc/source/core/data/funcdesc.cxx b/sc/source/core/data/funcdesc.cxx
index 7c37b12f3d65..6768dd6f8bcd 100644
--- a/sc/source/core/data/funcdesc.cxx
+++ b/sc/source/core/data/funcdesc.cxx
@@ -408,6 +408,7 @@ ScFunctionList::ScFunctionList()
{ SC_OPCODE_GET_ACT_TIME, ENTRY(SC_OPCODE_GET_ACT_TIME_ARY), 0, ID_FUNCTION_GRP_DATETIME, HID_FUNC_JETZT, 0, { } },
{ SC_OPCODE_NO_VALUE, ENTRY(SC_OPCODE_NO_VALUE_ARY), 0, ID_FUNCTION_GRP_INFO, HID_FUNC_NV, 0, { } },
{ SC_OPCODE_CURRENT, ENTRY(SC_OPCODE_CURRENT_ARY), 0, ID_FUNCTION_GRP_INFO, HID_FUNC_AKTUELL, 0, { } },
+ { SC_OPCODE_RANDOM_NV, ENTRY(SC_OPCODE_RANDOM_NV_ARY), 0, ID_FUNCTION_GRP_MATH, HID_FUNC_RAND_NV, 0, { } },
{ SC_OPCODE_DEG, ENTRY(SC_OPCODE_DEG_ARY), 0, ID_FUNCTION_GRP_MATH, HID_FUNC_DEG, 1, { 0 } },
{ SC_OPCODE_RAD, ENTRY(SC_OPCODE_RAD_ARY), 0, ID_FUNCTION_GRP_MATH, HID_FUNC_RAD, 1, { 0 } },
{ SC_OPCODE_SIN, ENTRY(SC_OPCODE_SIN_ARY), 0, ID_FUNCTION_GRP_MATH, HID_FUNC_SIN, 1, { 0 } },
@@ -786,7 +787,8 @@ ScFunctionList::ScFunctionList()
{ SC_OPCODE_FINDB, ENTRY(SC_OPCODE_FINDB_ARY), 0, ID_FUNCTION_GRP_TEXT, HID_FUNC_FINDB, 3, { 0, 0, 1 } },
{ SC_OPCODE_SEARCHB, ENTRY(SC_OPCODE_SEARCHB_ARY), 0, ID_FUNCTION_GRP_TEXT, HID_FUNC_SEARCHB, 3, { 0, 0, 1 } },
{ SC_OPCODE_REGEX, ENTRY(SC_OPCODE_REGEX_ARY), 0, ID_FUNCTION_GRP_TEXT, HID_FUNC_REGEX, 4, { 0, 0, 1, 1 } },
- { SC_OPCODE_FOURIER, ENTRY(SC_OPCODE_FOURIER_ARY), 0, ID_FUNCTION_GRP_MATRIX, HID_FUNC_FOURIER, 5, { 0, 0, 1, 1, 1 } }
+ { SC_OPCODE_FOURIER, ENTRY(SC_OPCODE_FOURIER_ARY), 0, ID_FUNCTION_GRP_MATRIX, HID_FUNC_FOURIER, 5, { 0, 0, 1, 1, 1 } },
+ { SC_OPCODE_RANDBETWEEN_NV, ENTRY(SC_OPCODE_RANDBETWEEN_NV_ARY), 0, ID_FUNCTION_GRP_MATH, HID_FUNC_RANDBETWEEN_NV, 2, { 0, 0 } }
};
ScFuncDesc* pDesc = nullptr;
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index 4cecd7ef3058..9aaeeb96259c 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -530,6 +530,9 @@ private:
void ScUnionFunc();
void ScPi();
void ScRandom();
+ void ScRandbetween();
+ void ScRandomImpl( const std::function<double( double fFirst, double fLast )>& RandomFunc,
+ double fFirst, double fLast );
void ScTrue();
void ScFalse();
void ScDeg();
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 03a8f46731a6..839c5135d665 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -1736,13 +1736,14 @@ void ScInterpreter::ScPi()
PushDouble(F_PI);
}
-void ScInterpreter::ScRandom()
+void ScInterpreter::ScRandomImpl( const std::function<double( double fFirst, double fLast )>& RandomFunc,
+ double fFirst, double fLast )
{
if (bMatrixFormula)
{
SCCOL nCols = 0;
SCROW nRows = 0;
- if(pMyFormulaCell)
+ if (pMyFormulaCell)
pMyFormulaCell->GetMatColsRows( nCols, nRows);
if (nCols == 1 && nRows == 1)
@@ -1752,7 +1753,7 @@ void ScInterpreter::ScRandom()
// default are executed in array context unless
// FA.setPropertyValue("IsArrayFunction",False) was set, return a
// scalar double instead of a 1x1 matrix object. tdf#128218
- PushDouble( comphelper::rng::uniform_real_distribution());
+ PushDouble( RandomFunc( fFirst, fLast));
return;
}
@@ -1773,7 +1774,7 @@ void ScInterpreter::ScRandom()
{
for (SCROW j=0; j < nRows; ++j)
{
- pResMat->PutDouble( comphelper::rng::uniform_real_distribution(),
+ pResMat->PutDouble( RandomFunc( fFirst, fLast),
static_cast<SCSIZE>(i), static_cast<SCSIZE>(j));
}
}
@@ -1782,8 +1783,39 @@ void ScInterpreter::ScRandom()
}
else
{
- PushDouble( comphelper::rng::uniform_real_distribution());
+ PushDouble( RandomFunc( fFirst, fLast));
+ }
+}
+
+void ScInterpreter::ScRandom()
+{
+ auto RandomFunc = []( double, double )
+ {
+ return comphelper::rng::uniform_real_distribution();
+ };
+ ScRandomImpl( RandomFunc, 0.0, 0.0);
+}
+
+void ScInterpreter::ScRandbetween()
+{
+ if (!MustHaveParamCount( GetByte(), 2))
+ return;
+
+ // Same like scaddins/source/analysis/analysis.cxx
+ // AnalysisAddIn::getRandbetween()
+ double fMax = rtl::math::round( GetDouble(), 0, rtl_math_RoundingMode_Up);
+ double fMin = rtl::math::round( GetDouble(), 0, rtl_math_RoundingMode_Up);
+ if (nGlobalError != FormulaError::NONE || fMin > fMax)
+ {
+ PushIllegalArgument();
+ return;
}
+ fMax = std::nextafter( fMax+1, -DBL_MAX);
+ auto RandomFunc = []( double fFirst, double fLast )
+ {
+ return floor( comphelper::rng::uniform_real_distribution( fFirst, fLast));
+ };
+ ScRandomImpl( RandomFunc, fMin, fMax);
}
void ScInterpreter::ScTrue()
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index 6fd4da8a1e36..7a6f03026121 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -4062,6 +4062,8 @@ StackVar ScInterpreter::Interpret()
case ocPercentSign : ScPercentSign(); break;
case ocPi : ScPi(); break;
case ocRandom : ScRandom(); break;
+ case ocRandomNV : ScRandom(); break;
+ case ocRandbetweenNV : ScRandbetween(); break;
case ocTrue : ScTrue(); break;
case ocFalse : ScFalse(); break;
case ocGetActDate : ScGetActDate(); break;
diff --git a/sc/source/core/tool/parclass.cxx b/sc/source/core/tool/parclass.cxx
index 3f9843fb333c..b2f0914b680a 100644
--- a/sc/source/core/tool/parclass.cxx
+++ b/sc/source/core/tool/parclass.cxx
@@ -221,6 +221,7 @@ const ScParameterClassification::RawData ScParameterClassification::pRawData[] =
{ ocQuartile_Inc, {{ Reference, Value }, 0, Value }},
{ ocRSQ, {{ ForceArray, ForceArray }, 0, Value }},
{ ocRandom, {{ Bounds }, 0, Value }},
+ { ocRandomNV, {{ Bounds }, 0, Value }},
{ ocRange, {{ Reference, Reference }, 0, Reference }},
{ ocRank, {{ Value, Reference, Value }, 0, Value }},
{ ocRank_Avg, {{ Value, Reference, Value }, 0, Value }},
diff --git a/sc/source/filter/excel/xlformula.cxx b/sc/source/filter/excel/xlformula.cxx
index c4037b4c9d91..30db442f67de 100644
--- a/sc/source/filter/excel/xlformula.cxx
+++ b/sc/source/filter/excel/xlformula.cxx
@@ -638,7 +638,9 @@ static const XclFunctionInfo saFuncTable_OOoLO[] =
EXC_FUNCENTRY_OOO( ocForecast_ETS_STM, 3, 6, 0, "ORG.LIBREOFFICE.FORECAST.ETS.STAT.MULT" ),
EXC_FUNCENTRY_OOO( ocRoundSig, 2, 2, 0, "ORG.LIBREOFFICE.ROUNDSIG" ),
EXC_FUNCENTRY_OOO( ocRegex, 2, 4, 0, "ORG.LIBREOFFICE.REGEX" ),
- EXC_FUNCENTRY_OOO( ocFourier, 2, 5, 0, "ORG.LIBREOFFICE.FOURIER" )
+ EXC_FUNCENTRY_OOO( ocFourier, 2, 5, 0, "ORG.LIBREOFFICE.FOURIER" ),
+ EXC_FUNCENTRY_OOO( ocRandomNV, 0, 0, 0, "ORG.LIBREOFFICE.RAND.NV" ),
+ EXC_FUNCENTRY_OOO( ocRandbetweenNV, 2, 2, 0, "ORG.LIBREOFFICE.RANDBETWEEN.NV" )
};
#undef EXC_FUNCENTRY_OOO_IBR
diff --git a/sc/source/filter/oox/formulabase.cxx b/sc/source/filter/oox/formulabase.cxx
index b2c074a1d277..f29c922a26ba 100644
--- a/sc/source/filter/oox/formulabase.cxx
+++ b/sc/source/filter/oox/formulabase.cxx
@@ -915,7 +915,9 @@ static const FunctionData saFuncTableOOoLO[] =
{ "ORG.LIBREOFFICE.FORECAST.ETS.STAT.MULT", "ORG.LIBREOFFICE.FORECAST.ETS.STAT.MULT", NOID, NOID, 3, 6, V, { VR, VA, VR }, FuncFlags::MACROCALL_NEW },
{ "ORG.LIBREOFFICE.ROUNDSIG", "ORG.LIBREOFFICE.ROUNDSIG", NOID, NOID, 2, 2, V, { RX }, FuncFlags::MACROCALL_NEW },
{ "ORG.LIBREOFFICE.REGEX", "ORG.LIBREOFFICE.REGEX", NOID, NOID, 2, 4, V, { RX }, FuncFlags::MACROCALL_NEW },
- { "ORG.LIBREOFFICE.FOURIER", "ORG.LIBREOFFICE.FOURIER", NOID, NOID, 2, 5, A, { RX }, FuncFlags::MACROCALL_NEW }
+ { "ORG.LIBREOFFICE.FOURIER", "ORG.LIBREOFFICE.FOURIER", NOID, NOID, 2, 5, A, { RX }, FuncFlags::MACROCALL_NEW },
+ { "ORG.LIBREOFFICE.RAND.NV", "ORG.LIBREOFFICE.RAND.NV", NOID, NOID, 0, 0, V, {}, FuncFlags::MACROCALL_NEW },
+ { "ORG.LIBREOFFICE.RANDBETWEEN.NV", "ORG.LIBREOFFICE.RANDBETWEEN.NV", NOID, NOID, 2, 2, V, { VR }, FuncFlags::MACROCALL_NEW }
};