Date: prev next · Thread: first prev next last
2011 Archives by date, by thread · List index


I came across this feature request today and decided to try my hand at
it. Is the attached patch an appropriate solution?

August Sodora
augsod@gmail.com
(201) 280-8138
From df0bb0d95a4343ac13aff62328c62511afaaa92b Mon Sep 17 00:00:00 2001
From: August Sodora <augsod@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


Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.