I came across this feature request today and decided to try my hand at it. Is the attached patch an appropriate solution?
August Sodora aug...@gmail.com (201) 280-8138
From df0bb0d95a4343ac13aff62328c62511afaaa92b Mon Sep 17 00:00:00 2001 From: August Sodora <aug...@gmail.com> Date: Thu, 20 Oct 2011 23:08:45 -0400 Subject: [PATCH] Added Frac function to calc formulas and BASIC standard library --- basic/source/runtime/methods1.cxx | 20 ++++++++++++++++++++ basic/source/runtime/rtlproto.hxx | 1 + basic/source/runtime/stdobj.cxx | 2 ++ formula/inc/formula/compiler.hrc | 5 +++-- formula/inc/formula/opcode.hxx | 1 + formula/source/core/resource/core_resource.src | 5 +++++ sc/source/core/inc/interpre.hxx | 1 + sc/source/core/tool/interpr2.cxx | 9 +++++++++ sc/source/core/tool/interpr4.cxx | 1 + 9 files changed, 43 insertions(+), 2 deletions(-) diff --git a/basic/source/runtime/methods1.cxx b/basic/source/runtime/methods1.cxx index f54ff7b..603277f 100644 --- a/basic/source/runtime/methods1.cxx +++ b/basic/source/runtime/methods1.cxx @@ -2531,6 +2531,26 @@ RTLFUNC(FormatDateTime) rPar.Get(0)->PutString( aRetStr ); } +RTLFUNC(Frac) +{ + (void)pBasic; + (void)bWrite; + + sal_uInt16 nParCount = rPar.Count(); + if( nParCount != 2) + { + StarBASIC::Error( SbERR_BAD_ARGUMENT ); + return; + } + + SbxVariable *pSbxVariable = rPar.Get(1); + double dVal = pSbxVariable->GetDouble(); + if(dVal >= 0) + rPar.Get(0)->PutDouble(dVal - ::rtl::math::approxFloor(dVal)); + else + rPar.Get(0)->PutDouble(dVal - ::rtl::math::approxCeil(dVal)); +} + RTLFUNC(Round) { (void)pBasic; diff --git a/basic/source/runtime/rtlproto.hxx b/basic/source/runtime/rtlproto.hxx index 469cd0f..101c320 100644 --- a/basic/source/runtime/rtlproto.hxx +++ b/basic/source/runtime/rtlproto.hxx @@ -250,6 +250,7 @@ extern RTLFUNC(Format); extern RTLFUNC(GetAttr); extern RTLFUNC(Randomize); // JSM extern RTLFUNC(Round); +extern RTLFUNC(Frac); extern RTLFUNC(Rnd); extern RTLFUNC(Shell); extern RTLFUNC(VarType); diff --git a/basic/source/runtime/stdobj.cxx b/basic/source/runtime/stdobj.cxx index 72ec66a..398ab53 100644 --- a/basic/source/runtime/stdobj.cxx +++ b/basic/source/runtime/stdobj.cxx @@ -289,6 +289,8 @@ static Methods aMethods[] = { { "Name", SbxSTRING, 0,NULL,0 }, { "Fix", SbxDOUBLE, 1 | _FUNCTION, RTLNAME(Fix),0 }, { "number", SbxDOUBLE, 0,NULL,0 }, +{ "Frac", SbxDOUBLE, 1 | _FUNCTION, RTLNAME(Frac),0 }, + { "number", SbxDOUBLE, 0,NULL,0 }, { "Format", SbxSTRING, 2 | _FUNCTION, RTLNAME(Format),0 }, { "expression", SbxVARIANT, 0,NULL,0 }, { "format", SbxSTRING, _OPT, NULL,0 }, diff --git a/formula/inc/formula/compiler.hrc b/formula/inc/formula/compiler.hrc index 15d8aab..fe093be 100755 --- a/formula/inc/formula/compiler.hrc +++ b/formula/inc/formula/compiler.hrc @@ -399,8 +399,9 @@ #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 */ +#define SC_OPCODE_STOP_2_PAR 401 +#define SC_OPCODE_FRAC 400 +#define SC_OPCODE_LAST_OPCODE_ID 400 /* last OpCode */ /*** Interna ***/ #define SC_OPCODE_INTERNAL_BEGIN 9999 diff --git a/formula/inc/formula/opcode.hxx b/formula/inc/formula/opcode.hxx index b1e585c..adfe26b 100644 --- a/formula/inc/formula/opcode.hxx +++ b/formula/inc/formula/opcode.hxx @@ -198,6 +198,7 @@ enum OpCodeEnum ocRoundUp = SC_OPCODE_ROUND_UP, ocRoundDown = SC_OPCODE_ROUND_DOWN, ocTrunc = SC_OPCODE_TRUNC, + ocFrac = SC_OPCODE_FRAC, ocLog = SC_OPCODE_LOG, ocPower = SC_OPCODE_POWER, ocGCD = SC_OPCODE_GGT, diff --git a/formula/source/core/resource/core_resource.src b/formula/source/core/resource/core_resource.src index e42a06d..b0cd749 100644 --- a/formula/source/core/resource/core_resource.src +++ b/formula/source/core/resource/core_resource.src @@ -156,6 +156,7 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH_ODFF String SC_OPCODE_ROUND_UP { Text = "ROUNDUP" ; }; String SC_OPCODE_ROUND_DOWN { Text = "ROUNDDOWN" ; }; String SC_OPCODE_TRUNC { Text = "TRUNC" ; }; + String SC_OPCODE_FRAC { Text = "FRAC" ; }; String SC_OPCODE_LOG { Text = "LOG" ; }; String SC_OPCODE_POWER { Text = "POWER" ; }; String SC_OPCODE_GGT { Text = "GCD" ; }; @@ -1119,6 +1120,10 @@ Resource RID_STRLIST_FUNCTION_NAMES { Text [ en-US ] = "TRUNC" ; }; + String SC_OPCODE_FRAC + { + Text [ en-US ] = "FRAC" ; + }; String SC_OPCODE_LOG { Text [ en-US ] = "LOG"; diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx index a693f58..c35c598 100644 --- a/sc/source/core/inc/interpre.hxx +++ b/sc/source/core/inc/interpre.hxx @@ -597,6 +597,7 @@ void ScFloor(); void RoundNumber( rtl_math_RoundingMode eMode ); void ScRound(); void ScRoundUp(); +void ScFrac(); void ScRoundDown(); void ScGetDateValue(); void ScGetTimeValue(); diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx index bbde6aa..83562e4f 100644 --- a/sc/source/core/tool/interpr2.cxx +++ b/sc/source/core/tool/interpr2.cxx @@ -455,6 +455,15 @@ void ScInterpreter::ScInt() PushDouble(::rtl::math::approxFloor(GetDouble())); } +void ScInterpreter::ScFrac() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScFrac" ); + double nVal = GetDouble(); + if(nVal >= 0) + PushDouble(nVal - ::rtl::math::approxFloor(nVal)); + else + PushDouble(nVal - ::rtl::math::approxCeil(nVal)); +} void ScInterpreter::RoundNumber( rtl_math_RoundingMode eMode ) { diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx index 261403e..d8344dd 100644 --- a/sc/source/core/tool/interpr4.cxx +++ b/sc/source/core/tool/interpr4.cxx @@ -3871,6 +3871,7 @@ StackVar ScInterpreter::Interpret() case ocRoundDown : ScRoundDown(); break; case ocCeil : ScCeil(); break; case ocFloor : ScFloor(); break; + case ocFrac : ScFrac(); break; case ocSumProduct : ScSumProduct(); break; case ocSumSQ : ScSumSQ(); break; case ocSumX2MY2 : ScSumX2MY2(); break; -- 1.7.4.4
_______________________________________________ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice