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

Reply via email to