kspread Library API Documentation

valuecalc.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 2005 Tomas Mecir <mecirt@gmail.com>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017    Boston, MA 02111-1307, USA.
00018 */
00019 
00020 #include "valuecalc.h"
00021 
00022 #include "valueconverter.h"
00023 
00024 #include <math.h>
00025 
00026 using namespace KSpread;
00027 
00028 ValueCalc::ValueCalc (ValueConverter* conv): converter( conv )
00029 {
00030 }
00031 
00032 KSpreadValue ValueCalc::add (const KSpreadValue &a, const KSpreadValue &b)
00033 {
00034   double aa, bb;
00035   aa = converter->asFloat (a).asFloat();
00036   bb = converter->asFloat (b).asFloat();
00037   KSpreadValue res = KSpreadValue (aa + bb);
00038 
00039   if (a.isNumber())
00040     res.setFormat (format (a.format(), b.format()));
00041 
00042   return res;
00043 }
00044 
00045 KSpreadValue ValueCalc::sub (const KSpreadValue &a, const KSpreadValue &b)
00046 {
00047   double aa, bb;
00048   aa = converter->asFloat (a).asFloat();
00049   bb = converter->asFloat (b).asFloat();
00050   KSpreadValue res = KSpreadValue (aa - bb);
00051 
00052   if (a.isNumber())
00053     res.setFormat (format (a.format(), b.format()));
00054 
00055   return res;
00056 }
00057 
00058 KSpreadValue ValueCalc::mul (const KSpreadValue &a, const KSpreadValue &b)
00059 {
00060   double aa, bb;
00061   aa = converter->asFloat (a).asFloat();
00062   bb = converter->asFloat (b).asFloat();
00063   KSpreadValue res = KSpreadValue (aa * bb);
00064 
00065   if (a.isNumber())
00066     res.setFormat (format (a.format(), b.format()));
00067 
00068   return res;
00069 }
00070 
00071 KSpreadValue ValueCalc::div (const KSpreadValue &a, const KSpreadValue &b)
00072 {
00073   double aa, bb;
00074   aa = converter->asFloat (a).asFloat();
00075   bb = converter->asFloat (b).asFloat();
00076   KSpreadValue res;
00077   if (bb == 0.0)
00078     return KSpreadValue::errorDIV0();
00079   else
00080     res = KSpreadValue (aa / bb);
00081 
00082   if (a.isNumber())
00083     res.setFormat (format (a.format(), b.format()));
00084 
00085   return res;
00086 }
00087 
00088 KSpreadValue ValueCalc::pow (const KSpreadValue &a, const KSpreadValue &b)
00089 {
00090   double aa, bb;
00091   aa = converter->asFloat (a).asFloat();
00092   bb = converter->asFloat (b).asFloat();
00093   KSpreadValue res = KSpreadValue (::pow (aa, bb));
00094 
00095   if (a.isNumber())
00096     res.setFormat (format (a.format(), b.format()));
00097 
00098   return res;
00099 }
00100 
00101 KSpreadValue ValueCalc::add (const KSpreadValue &a, double b)
00102 {
00103   KSpreadValue res = KSpreadValue (converter->asFloat(a).asFloat() + b);
00104 
00105   if (a.isNumber())
00106     res.setFormat (a.format());
00107 
00108   return res;
00109 }
00110 
00111 KSpreadValue ValueCalc::sub (const KSpreadValue &a, double b)
00112 {
00113   KSpreadValue res = KSpreadValue (converter->asFloat(a).asFloat() - b);
00114 
00115   if (a.isNumber())
00116     res.setFormat (a.format());
00117 
00118   return res;
00119 }
00120 
00121 KSpreadValue ValueCalc::mul (const KSpreadValue &a, double b)
00122 {
00123   KSpreadValue res = KSpreadValue (converter->asFloat(a).asFloat() * b);
00124 
00125   if (a.isNumber())
00126     res.setFormat (a.format());
00127 
00128   return res;
00129 }
00130 
00131 KSpreadValue ValueCalc::div (const KSpreadValue &a, double b)
00132 {
00133   KSpreadValue res;
00134   if (b == 0.0)
00135     return KSpreadValue::errorDIV0();
00136 
00137   res = KSpreadValue (converter->asFloat(a).asFloat() / b);
00138 
00139   if (a.isNumber())
00140     res.setFormat (a.format());
00141 
00142   return res;
00143 }
00144 
00145 KSpreadValue ValueCalc::pow (const KSpreadValue &a, double b)
00146 {
00147   KSpreadValue res = KSpreadValue (::pow (converter->asFloat(a).asFloat(), b));
00148 
00149   if (a.isNumber())
00150     res.setFormat (a.format());
00151 
00152   return res;
00153 }
00154 
00155 KSpreadValue ValueCalc::log (const KSpreadValue &number,
00156     const KSpreadValue &base)
00157 {
00158   double logbase = converter->asFloat (base).asFloat();
00159   if (logbase == 1.0)
00160     return KSpreadValue::errorDIV0();
00161   if (logbase <= 0.0)
00162     return KSpreadValue::errorNA();
00163 
00164   logbase = log10 (logbase);
00165   KSpreadValue res = KSpreadValue (log10 (converter->asFloat (number).asFloat()) / logbase);
00166 
00167   if (number.isNumber())
00168     res.setFormat (number.format());
00169 
00170   return res;
00171 }
00172 
00173 KSpreadValue ValueCalc::ln (const KSpreadValue &number)
00174 {
00175   KSpreadValue res = KSpreadValue (::log (converter->asFloat (number).asFloat()));
00176 
00177   if (number.isNumber())
00178     res.setFormat (number.format());
00179 
00180   return res;
00181 }
00182 
00183 KSpreadValue ValueCalc::log (const KSpreadValue &number, double base)
00184 {
00185   if (base <= 0.0)
00186     return KSpreadValue::errorNA();
00187   if (base == 1.0)
00188     return KSpreadValue::errorDIV0();
00189 
00190   double num = converter->asFloat (number).asFloat();
00191   KSpreadValue res = KSpreadValue (log10 (num) / log10 (base));
00192 
00193   if (number.isNumber())
00194     res.setFormat (number.format());
00195 
00196   return res;
00197 }
00198 
00199 // ------------------------------------------------------
00200 
00201 KSpreadValue ValueCalc::sum (const KSpreadValue &range)
00202 {
00203   if (!range.isArray())
00204     return converter->asFloat (range);
00205 
00206   //if we are here, we have an array
00207   KSpreadValue res;
00208   KSpreadValue::Format fmt = KSpreadValue::fmt_None;
00209 
00210   int rows = range.rows ();
00211   int cols = range.columns ();
00212   for (int r = 0; r < rows; r++)
00213     for (int c = 0; c < cols; c++)
00214     {
00215       KSpreadValue v = range.element (c, r);
00216       if (v.isArray())
00217         res = add (res, sum (v));
00218       else
00219         res = add (res, v);
00220       if (fmt == KSpreadValue::fmt_None)
00221         fmt = range.element (c, r).format ();
00222     }
00223 
00224   res.setFormat (fmt);
00225   return res;
00226 }
00227 
00228 int ValueCalc::count (const KSpreadValue &range)
00229 {
00230   if (!range.isArray())
00231     return range.isEmpty() ? 0 : 1;
00232 
00233   int res = 0;
00234 
00235   int cols = range.columns ();
00236   int rows = range.rows ();
00237   for (int r = 0; r < rows; r++)
00238     for (int c = 0; c < cols; c++)
00239     {
00240       KSpreadValue v = range.element (c, r);
00241       if (v.isArray())
00242         res += count (v);
00243       else
00244         if (!v.isEmpty() && !v.isString())
00245           res++;
00246     }
00247 
00248   return res;
00249 }
00250 
00251 int ValueCalc::countA (const KSpreadValue &range)
00252 {
00253   if (!range.isArray())
00254     return range.isEmpty() ? 0 : 1;
00255 
00256   int res = 0;
00257 
00258   int cols = range.columns ();
00259   int rows = range.rows ();
00260   for (int r = 0; r < rows; r++)
00261     for (int c = 0; c < cols; c++)
00262     {
00263       KSpreadValue v = range.element (c, r);
00264       if (v.isArray())
00265         res += countA (v);
00266       else
00267         if (!v.isEmpty())
00268           res++;
00269     }
00270 
00271   return res;
00272 }
00273 
00274 
00275 KSpreadValue ValueCalc::avg (const KSpreadValue &range)
00276 {
00277   int cnt = count (range);
00278   if (cnt)
00279     return div (sum (range), cnt);
00280   return KSpreadValue (0.0);
00281 }
00282 
00283 KSpreadValue ValueCalc::max (const KSpreadValue &range)
00284 {
00285   if (!range.isArray())
00286     return converter->asFloat (range);
00287 
00288   //if we are here, we have an array
00289   KSpreadValue res;
00290 
00291   int rows = range.rows ();
00292   int cols = range.columns ();
00293   bool got = false;
00294   for (int r = 0; r < rows; r++)
00295     for (int c = 0; c < cols; c++)
00296     {
00297       KSpreadValue v = range.element (c, r);
00298       if (v.isArray())
00299         v = max (v);
00300       if (!v.isEmpty ())
00301         if (got)
00302         {
00303           if (v.greater (res))
00304             res = v;
00305         }
00306         else
00307         {
00308           res = v;
00309           got = true;
00310         }
00311     }
00312 
00313   return res;
00314 }
00315 
00316 KSpreadValue ValueCalc::min (const KSpreadValue &range)
00317 {
00318   if (!range.isArray())
00319     return converter->asFloat (range);
00320 
00321   //if we are here, we have an array
00322   KSpreadValue res;
00323 
00324   int rows = range.rows ();
00325   int cols = range.columns ();
00326   bool got = false;
00327   for (int r = 0; r < rows; r++)
00328     for (int c = 0; c < cols; c++)
00329     {
00330       KSpreadValue v = range.element (c, r);
00331       if (v.isArray())
00332         v = max (v);
00333       if (!v.isEmpty ())
00334         if (got)
00335         {
00336           if (v.less (res))
00337             res = v;
00338         }
00339         else
00340         {
00341           res = v;
00342           got = true;
00343         }
00344     }
00345 
00346   return res;
00347 }
00348 
00349 KSpreadValue::Format ValueCalc::format (KSpreadValue::Format a,
00350     KSpreadValue::Format b)
00351 {
00352   if ((a == KSpreadValue::fmt_None) || (a == KSpreadValue::fmt_Boolean))
00353     return b;
00354   return a;
00355 }
00356 
KDE Logo
This file is part of the documentation for kspread Library Version 1.4.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Mon Feb 13 09:43:38 2006 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003