kspread Library API Documentation

kspread_functions_math.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 1998-2002 The KSpread Team
00003                            www.koffice.org/kspread
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00018    Boston, MA 02111-1307, USA.
00019 */
00020 
00021 // built-in math functions
00022 
00023 #include <stdlib.h>
00024 #include <math.h>
00025 #include <float.h>
00026 
00027 #include <kdebug.h>
00028 #include <klocale.h>
00029 
00030 #include <koscript_parser.h>
00031 #include <koscript_util.h>
00032 #include <koscript_func.h>
00033 #include <koscript_synext.h>
00034 
00035 #include "kspread_cell.h"
00036 #include "kspread_sheet.h"
00037 #include "kspread_interpreter.h"
00038 #include "kspread_doc.h"
00039 #include "kspread_functions.h"
00040 #include "kspread_functions_helper.h"
00041 #include "kspread_util.h"
00042 
00043 namespace math_local
00044 {
00045   KSpreadCell * gCell = 0;
00046 }
00047 
00048 using namespace math_local;
00049 
00050 // prototypes
00051 bool kspreadfunc_abs( KSContext& context );
00052 bool kspreadfunc_ceil( KSContext& context );
00053 bool kspreadfunc_ceiling( KSContext& context );
00054 bool kspreadfunc_count( KSContext& context );
00055 bool kspreadfunc_counta( KSContext& context );
00056 bool kspreadfunc_countblank( KSContext& context );
00057 bool kspreadfunc_countif( KSContext& context );
00058 bool kspreadfunc_cur( KSContext& context );
00059 bool kspreadfunc_div( KSContext& context );
00060 bool kspreadfunc_eps( KSContext& context );
00061 bool kspreadfunc_even( KSContext& context );
00062 bool kspreadfunc_exp( KSContext& context );
00063 bool kspreadfunc_fact( KSContext& context );
00064 bool kspreadfunc_factdouble( KSContext& context );
00065 bool kspreadfunc_fib( KSContext& context );
00066 bool kspreadfunc_floor( KSContext& context );
00067 bool kspreadfunc_gcd( KSContext & context );
00068 bool kspreadfunc_int( KSContext& context );
00069 bool kspreadfunc_inv( KSContext& context );
00070 bool kspreadfunc_kproduct( KSContext& context );
00071 bool kspreadfunc_lcm( KSContext & context );
00072 bool kspreadfunc_ln( KSContext& context );
00073 bool kspreadfunc_log( KSContext& context );
00074 bool kspreadfunc_log2( KSContext& context );
00075 bool kspreadfunc_log10( KSContext& context );
00076 bool kspreadfunc_logn( KSContext& context );
00077 bool kspreadfunc_max( KSContext& context );
00078 bool kspreadfunc_maxa( KSContext& context );
00079 bool kspreadfunc_min( KSContext& context );
00080 bool kspreadfunc_mina( KSContext& context );
00081 bool kspreadfunc_mod( KSContext& context );
00082 bool kspreadfunc_mround( KSContext& context );
00083 bool kspreadfunc_mult( KSContext& context );
00084 bool kspreadfunc_multinomial( KSContext& context );
00085 bool kspreadfunc_odd( KSContext& context );
00086 bool kspreadfunc_pow( KSContext& context );
00087 bool kspreadfunc_quotient( KSContext& context );
00088 bool kspreadfunc_product( KSContext& context );
00089 bool kspreadfunc_rand( KSContext& context );
00090 bool kspreadfunc_randbetween( KSContext& context );
00091 bool kspreadfunc_randbernoulli( KSContext & context );
00092 bool kspreadfunc_randbinom( KSContext & context );
00093 bool kspreadfunc_randexp( KSContext & context );
00094 bool kspreadfunc_randnegbinom( KSContext & context );
00095 bool kspreadfunc_randnorm( KSContext & context );
00096 bool kspreadfunc_randpoisson( KSContext & context );
00097 bool kspreadfunc_rootn( KSContext& context );
00098 bool kspreadfunc_round( KSContext& context );
00099 bool kspreadfunc_rounddown( KSContext& context );
00100 bool kspreadfunc_roundup( KSContext& context );
00101 bool kspreadfunc_sign( KSContext& context );
00102 bool kspreadfunc_sqrt( KSContext& context );
00103 bool kspreadfunc_sqrtpi( KSContext& context );
00104 bool kspreadfunc_subtotal( KSContext& context );
00105 bool kspreadfunc_sum( KSContext& context );
00106 bool kspreadfunc_sumif( KSContext& context );
00107 bool kspreadfunc_suma( KSContext& context );
00108 bool kspreadfunc_sumsq( KSContext& context );
00109 bool kspreadfunc_trunc( KSContext& context );
00110 
00111 
00112 bool kspreadfunc_multipleOP( KSContext& context );
00113 
00114 // registers all math functions
00115 void KSpreadRegisterMathFunctions()
00116 {
00117   gCell = 0;
00118   KSpreadFunctionRepository * repo = KSpreadFunctionRepository::self();
00119 
00120   repo->registerFunction( "MULTIPLEOPERATIONS", kspreadfunc_multipleOP );
00121 
00122   repo->registerFunction( "ABS",           kspreadfunc_abs );
00123   repo->registerFunction( "CEIL",          kspreadfunc_ceil );
00124   repo->registerFunction( "CEILING",       kspreadfunc_ceiling );
00125   repo->registerFunction( "COUNT",         kspreadfunc_count );
00126   repo->registerFunction( "COUNTA",        kspreadfunc_counta );
00127   repo->registerFunction( "COUNTBLANK",    kspreadfunc_countblank );
00128   repo->registerFunction( "COUNTIF",       kspreadfunc_countif );
00129   repo->registerFunction( "CUR",           kspreadfunc_cur );
00130   repo->registerFunction( "DIV",           kspreadfunc_div );
00131   repo->registerFunction( "EPS",           kspreadfunc_eps );
00132   repo->registerFunction( "EVEN",          kspreadfunc_even );
00133   repo->registerFunction( "EXP",           kspreadfunc_exp );
00134   repo->registerFunction( "FACT",          kspreadfunc_fact );
00135   repo->registerFunction( "FACTDOUBLE",    kspreadfunc_factdouble );
00136   repo->registerFunction( "FIB",           kspreadfunc_fib ); // KSpread-specific, like Quattro-Pro's FIB
00137   repo->registerFunction( "FLOOR",         kspreadfunc_floor );
00138   repo->registerFunction( "G_PRODUCT",     kspreadfunc_kproduct ); // Gnumeric compatibility
00139   repo->registerFunction( "GCD",           kspreadfunc_gcd );
00140   repo->registerFunction( "INT",           kspreadfunc_int );
00141   repo->registerFunction( "INV",           kspreadfunc_inv );
00142   repo->registerFunction( "KPRODUCT",      kspreadfunc_kproduct );
00143   repo->registerFunction( "LCD",           kspreadfunc_gcd ); // obsolete, use GCD instead, remove in 1.4
00144   repo->registerFunction( "LCM",           kspreadfunc_lcm );
00145   repo->registerFunction( "LN",            kspreadfunc_ln );
00146   repo->registerFunction( "LOG",           kspreadfunc_log );
00147   repo->registerFunction( "LOG2",          kspreadfunc_log2 );
00148   repo->registerFunction( "LOG10",         kspreadfunc_log10 );
00149   repo->registerFunction( "LOGN",          kspreadfunc_logn );
00150   repo->registerFunction( "MAX",           kspreadfunc_max );
00151   repo->registerFunction( "MAXA",          kspreadfunc_maxa );
00152   repo->registerFunction( "MIN",           kspreadfunc_min );
00153   repo->registerFunction( "MINA",          kspreadfunc_mina );
00154   repo->registerFunction( "MOD",           kspreadfunc_mod );
00155   repo->registerFunction( "MROUND",        kspreadfunc_mround );
00156   repo->registerFunction( "MULTIPLY",      kspreadfunc_mult );
00157   repo->registerFunction( "MULTINOMIAL",   kspreadfunc_multinomial );
00158   repo->registerFunction( "ODD",           kspreadfunc_odd );
00159   repo->registerFunction( "POW",           kspreadfunc_pow ); // remove in 1.5
00160   repo->registerFunction( "POWER",         kspreadfunc_pow );
00161   repo->registerFunction( "QUOTIENT",      kspreadfunc_quotient );
00162   repo->registerFunction( "PRODUCT",       kspreadfunc_product );
00163   repo->registerFunction( "RAND",          kspreadfunc_rand );
00164   repo->registerFunction( "RANDBERNOULLI", kspreadfunc_randbernoulli );
00165   repo->registerFunction( "RANDBETWEEN",   kspreadfunc_randbetween );
00166   repo->registerFunction( "RANDBINOM",     kspreadfunc_randbinom );
00167   repo->registerFunction( "RANDEXP",       kspreadfunc_randexp );
00168   repo->registerFunction( "RANDNEGBINOM",  kspreadfunc_randnegbinom );
00169   repo->registerFunction( "RANDNORM",      kspreadfunc_randnorm );
00170   repo->registerFunction( "RANDPOISSON",   kspreadfunc_randpoisson );
00171   repo->registerFunction( "ROOTN",         kspreadfunc_rootn );
00172   repo->registerFunction( "ROUND",         kspreadfunc_round );
00173   repo->registerFunction( "ROUNDDOWN",     kspreadfunc_rounddown );
00174   repo->registerFunction( "ROUNDUP",       kspreadfunc_roundup );
00175   repo->registerFunction( "SIGN",          kspreadfunc_sign );
00176   repo->registerFunction( "SQRT",          kspreadfunc_sqrt );
00177   repo->registerFunction( "SQRTPI",        kspreadfunc_sqrtpi );
00178   repo->registerFunction( "SUBTOTAL",      kspreadfunc_subtotal );
00179   repo->registerFunction( "SUM",           kspreadfunc_sum );
00180   repo->registerFunction( "SUMIF",         kspreadfunc_sumif );
00181   repo->registerFunction( "SUMA",          kspreadfunc_suma );
00182   repo->registerFunction( "SUMSQ",         kspreadfunc_sumsq );
00183   repo->registerFunction( "TRUNC",         kspreadfunc_trunc );
00184 }
00185 
00186 // Function: SQRT
00187 bool kspreadfunc_sqrt( KSContext& context )
00188 {
00189   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00190 
00191   if ( !KSUtil::checkArgumentsCount( context, 1, "sqrt", true ) )
00192     return false;
00193   double val=0.0;
00194   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
00195     {
00196       if(!KSUtil::checkType( context, args[0], KSValue::Empty, true ))
00197     return false;
00198     }
00199   else
00200     val=args[0]->doubleValue();
00201 
00202   context.setValue( new KSValue( sqrt( val ) ) );
00203 
00204   return true;
00205 }
00206 
00207 // Function: SQRTPI
00208 bool kspreadfunc_sqrtpi( KSContext& context )
00209 {
00210   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00211 
00212   if ( !KSUtil::checkArgumentsCount( context, 1, "SQRTPI", true ) )
00213     return false;
00214   double val=0.0;
00215   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
00216     {
00217       if(!KSUtil::checkType( context, args[0], KSValue::Empty, true ))
00218     return false;
00219     }
00220   else
00221     val=args[0]->doubleValue();
00222 
00223   if( val < 0 ) return false;
00224 
00225   context.setValue( new KSValue( sqrt( val * M_PI ) ) );
00226   return true;
00227 }
00228 
00229 
00230 
00231 
00232 
00233 // Function: ROOTN
00234 bool kspreadfunc_rootn( KSContext& context )
00235 {
00236   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00237 
00238   if ( !KSUtil::checkArgumentsCount( context, 2, "SQRTn", true ) )
00239     return false;
00240 
00241   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
00242     return false;
00243   if ( !KSUtil::checkType( context, args[1], KSValue::IntType, true ) )
00244     return false;
00245 
00246   context.setValue( new KSValue( exp( log(args[0]->doubleValue())/args[1]->intValue() ) ) );
00247 
00248   return true;
00249 }
00250 
00251 // Function: CUR
00252 bool kspreadfunc_cur( KSContext& context )
00253 {
00254   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00255 
00256   if ( !KSUtil::checkArgumentsCount( context, 1, "CUR", true ) )
00257     return false;
00258 
00259   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
00260     return false;
00261 
00262   context.setValue( new KSValue( exp( log(args[0]->doubleValue())/3)) );
00263 
00264   return true;
00265 }
00266 
00267 // Function: ABS
00268 bool kspreadfunc_abs( KSContext& context )
00269 {
00270   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00271 
00272   if ( !KSUtil::checkArgumentsCount( context, 1, "ABS", true ) || !KSUtil::checkArgumentsCount( context, 1, "ABS", true ))
00273     return false;
00274 
00275   double val=0.0;
00276   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
00277     {
00278       if(!KSUtil::checkType( context, args[0], KSValue::Empty, true ))
00279     return false;
00280     }
00281   else
00282     val=args[0]->doubleValue();
00283 
00284   context.setValue( new KSValue( fabs(val ) ) );
00285 
00286   return true;
00287 }
00288 
00289 // Function: exp
00290 bool kspreadfunc_exp( KSContext& context )
00291 {
00292   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00293 
00294   if ( !KSUtil::checkArgumentsCount( context, 1, "exp",true ) )
00295     return false;
00296 
00297   double val=0.0;
00298   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
00299     {
00300       if(!KSUtil::checkType( context, args[0], KSValue::Empty, true ))
00301     return false;
00302     }
00303   else
00304     val=args[0]->doubleValue();
00305 
00306   context.setValue( new KSValue( exp( val ) ) );
00307 
00308   return true;
00309 }
00310 
00311 // Function: ceil
00312 bool kspreadfunc_ceil( KSContext& context )
00313 {
00314   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00315 
00316   if ( !KSUtil::checkArgumentsCount( context, 1, "CEIL", true ) )
00317     return false;
00318 
00319   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
00320     return false;
00321   if ( approx_equal( floor( args[0]->doubleValue() ), args[0]->doubleValue() ) )
00322     context.setValue( new KSValue( args[0]->doubleValue() ) );
00323   else
00324     context.setValue( new KSValue( ceil( args[0]->doubleValue() ) ) );
00325 
00326   return true;
00327 }
00328 
00329 // Function: ceiling
00330 bool kspreadfunc_ceiling( KSContext& context )
00331 {
00332   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00333 
00334   double res;
00335   double number;
00336 
00337   if ( !KSUtil::checkArgumentsCount( context, 2, "CEILING", true ) )
00338   {
00339     if ( !KSUtil::checkArgumentsCount( context, 1, "CEILING", true ) )
00340       return false;
00341 
00342     if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
00343       return false;
00344 
00345     number = args[0]->doubleValue();
00346 
00347     if ( number >= 0 )
00348       res = 1.0;
00349     else
00350       res = -1.0;
00351   }
00352   else
00353   {
00354     if ( !KSUtil::checkType( context, args[1], KSValue::DoubleType, true ) )
00355       return false;
00356 
00357     if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
00358       return false;
00359 
00360     number = args[0]->doubleValue();
00361 
00362     res = args[1]->doubleValue();
00363   }
00364 
00365   if ( res == 0 )
00366     return false;
00367 
00368   double d = number / res;
00369 
00370   if ( d < 0 )
00371     return false;
00372 
00373   if ( approx_equal( floor( d ), d ) )
00374     context.setValue( new KSValue( d * res ) );
00375   else
00376     context.setValue( new KSValue( ceil( d ) * res ) );
00377 
00378   return true;
00379 }
00380 
00381 // Function: floor
00382 bool kspreadfunc_floor( KSContext& context )
00383 {
00384   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00385 
00386   if ( !KSUtil::checkArgumentsCount( context, 1, "floor", true ) )
00387     return false;
00388 
00389   double val=0.0;
00390   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
00391     {
00392       if(!KSUtil::checkType( context, args[0], KSValue::Empty, true ))
00393     return false;
00394     }
00395   else
00396     val=args[0]->doubleValue();
00397 
00398   context.setValue( new KSValue( floor( val ) ) );
00399 
00400   return true;
00401 }
00402 
00403 // Function: ln
00404 bool kspreadfunc_ln( KSContext& context )
00405 {
00406   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00407 
00408   if ( !KSUtil::checkArgumentsCount( context, 1, "ln", true ) )
00409     return false;
00410 
00411   double val=0.0;
00412   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
00413     {
00414       if(!KSUtil::checkType( context, args[0], KSValue::Empty, true ))
00415     return false;
00416     }
00417   else
00418     val=args[0]->doubleValue();
00419 
00420   context.setValue( new KSValue( log( val ) ) );
00421 
00422   return true;
00423 }
00424 
00425 // Function: LOGn
00426 bool kspreadfunc_logn( KSContext& context )
00427 {
00428   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00429 
00430   if ( !KSUtil::checkArgumentsCount( context, 2, "LOGn", true ) )
00431     return false;
00432 
00433   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
00434     return false;
00435   if ( !KSUtil::checkType( context, args[1], KSValue::DoubleType, true ) )
00436     return false;
00437 
00438   context.setValue( new KSValue( log( args[0]->doubleValue() ) /log( args[1]->doubleValue() )) );
00439 
00440   return true;
00441 }
00442 
00443 // Function: LOG2
00444 bool kspreadfunc_log2( KSContext& context )
00445 {
00446   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00447 
00448   if ( !KSUtil::checkArgumentsCount( context, 1, "LOG2", true ) )
00449     return false;
00450 
00451   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
00452     return false;
00453 
00454   double d = args[0]->doubleValue();
00455 
00456   if ( d <= 0 )
00457     return false;
00458 
00459   context.setValue( new KSValue( log( d ) /log( 2.0 ) ) );
00460   return true;
00461 }
00462 
00463 // Function: LOG10
00464 bool kspreadfunc_log10( KSContext& context )
00465 {
00466   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00467 
00468   if ( !KSUtil::checkArgumentsCount( context, 1, "LOG10", true ) )
00469     return false;
00470 
00471   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
00472     return false;
00473 
00474   double d = args[0]->doubleValue();
00475 
00476   if ( d <= 0 )
00477     return false;
00478 
00479   context.setValue( new KSValue( log10( d ) ) );
00480   return true;
00481 }
00482 
00483 // Function: log
00484 bool kspreadfunc_log( KSContext& context )
00485 {
00486   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00487 
00488   if ( !KSUtil::checkArgumentsCount( context, 1, "log", true ) )
00489     return false;
00490 
00491   double val=0.0;
00492   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
00493     {
00494       if(!KSUtil::checkType( context, args[0], KSValue::Empty, true ))
00495     return false;
00496     }
00497   else
00498     val=args[0]->doubleValue();
00499 
00500   context.setValue( new KSValue( log10( val ) ) );
00501 
00502   return true;
00503 }
00504 
00505 static bool kspreadfunc_sum_helper( KSContext & context, QValueList<KSValue::Ptr> & args,
00506                                     double & result, bool aMode )
00507 {
00508   QValueList<KSValue::Ptr>::Iterator it = args.begin();
00509   QValueList<KSValue::Ptr>::Iterator end = args.end();
00510 
00511   for( ; it != end; ++it )
00512   {
00513     if ( KSUtil::checkType( context, *it, KSValue::ListType, false ) )
00514     {
00515       if ( !kspreadfunc_sum_helper( context, (*it)->listValue(), result, aMode ) )
00516         return false;
00517     }
00518     else if ( KSUtil::checkType( context, *it, KSValue::DoubleType, true ) )
00519     {
00520       result += (*it)->doubleValue();
00521     }
00522     else if ( aMode )
00523     {
00524       if ( KSUtil::checkType( context, *it, KSValue::StringType, false ) )
00525       {
00526         // TODO: needed?
00527       }
00528       else
00529       if ( KSUtil::checkType( context, *it, KSValue::BoolType, false ) )
00530       {
00531         result += ( (*it)->boolValue() ? 1.0 : 0.0 );
00532       }
00533     }
00534   }
00535 
00536   return true;
00537 }
00538 
00539 // Function: sum
00540 bool kspreadfunc_sum( KSContext & context )
00541 {
00542   double result = 0.0;
00543   bool b = kspreadfunc_sum_helper( context, context.value()->listValue(), result, false );
00544 
00545   if ( b )
00546     context.setValue( new KSValue( result ) );
00547 
00548   return b;
00549 }
00550 
00551 static bool kspreadfunc_sumif_helper( KSContext & context, KSValue *value,
00552                                       QValueList<KSValue::Ptr> &args,
00553                                       KSpreadDB::Condition &cond,
00554                                       double & result, int &vpos, int &hpos )
00555 {
00556   if ( KSUtil::checkType( context, value, KSValue::DoubleType, false ) )
00557   {
00558     if ( conditionMatches( cond, value->doubleValue() ) ) {
00559       if( hpos == -1 )
00560         result += value->doubleValue();
00561       else {
00562         result += (args[2]->listValue()[vpos])-> listValue()[hpos]->doubleValue();
00563         ++hpos;
00564       }
00565     }
00566     return true;
00567   }
00568 
00569   if ( KSUtil::checkType( context, value, KSValue::ListType, false ) ) {
00570     QValueList<KSValue::Ptr> values = value->listValue();
00571     QValueList<KSValue::Ptr>::Iterator it = values.begin();
00572     QValueList<KSValue::Ptr>::Iterator end = values.end();
00573 
00574     for( ; it != end; ++it ) {
00575       if( !kspreadfunc_sumif_helper( context, *it, args, cond, result, vpos, hpos ) )
00576         return false;
00577       if ( vpos != -1 && KSUtil::checkType( context, *it, KSValue::ListType, false ) ){
00578         ++vpos;
00579         hpos = 0;
00580       }
00581     }
00582     return true;
00583   }
00584   return false;
00585 }
00586 
00587 bool kspreadfunc_sumif( KSContext & context )
00588 {
00589   double result = 0.0;
00590   int hpos = -1; int vpos = -1; // these values become >=0 if there's a seperate sumrange
00591   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00592 
00593   // starting sanity checks
00594   if( KSUtil::checkArgumentsCount( context, 3, "SUMIF", true ) ) {
00595   
00596     QValueList<KSValue::Ptr> checkRange = args[0]->listValue();
00597     QValueList<KSValue::Ptr> sumRange   = args[2]->listValue();
00598 
00599     if( checkRange.count() <= sumRange.count() ) {
00600       for( uint i = 0 ; i < checkRange.count() ; ++i ) {
00601         if ( checkRange[i]->listValue().count() > sumRange[i]->listValue().count() )
00602           return false;
00603       }
00604       // the ranges do match, make hpos and vpos > -1
00605       hpos = 0;
00606       vpos = 0;
00607     } else return false;
00608 
00609   } else if ( !KSUtil::checkArgumentsCount( context, 2, "SUMIF", false ) )
00610       return false;
00611     
00612   if( !KSUtil::checkType( context, args[1], KSValue::StringType ) )
00613     return false;
00614   // end of sanity checks
00615 
00616   KSValue *value = args[0];
00617   KSpreadDB::Condition cond;
00618   getCond( cond, args[1]->stringValue() );
00619 
00620   bool b = kspreadfunc_sumif_helper( context, value, args, cond, result, vpos, hpos );
00621 
00622   if ( b ) {
00623     context.setValue( new KSValue( result ) );
00624   }
00625   return b;
00626 }
00627 
00628 // Function: suma
00629 bool kspreadfunc_suma( KSContext & context )
00630 {
00631   double result = 0.0;
00632   bool b = kspreadfunc_sum_helper( context, context.value()->listValue(), result, true );
00633 
00634   if ( b )
00635     context.setValue( new KSValue( result ) );
00636 
00637   return b;
00638 }
00639 
00640 static bool kspreadfunc_product_helper( KSContext & context,
00641                                         QValueList<KSValue::Ptr> & args,
00642                                         double & result, int & number )
00643 {
00644   QValueList<KSValue::Ptr>::Iterator it = args.begin();
00645   QValueList<KSValue::Ptr>::Iterator end = args.end();
00646 
00647   for( ; it != end; ++it )
00648   {
00649     if ( KSUtil::checkType( context, *it, KSValue::ListType, false ) )
00650     {
00651       if ( !kspreadfunc_product_helper( context, (*it)->listValue(), result, number ) )
00652         return false;
00653     }
00654     else if ( KSUtil::checkType( context, *it, KSValue::DoubleType, true ) )
00655     {
00656       ++number;
00657       result *= (*it)->doubleValue();
00658     }
00659   }
00660 
00661   return true;
00662 }
00663 
00664 // Function: product
00665 bool kspreadfunc_product( KSContext& context )
00666 {
00667   double result = 1.0;
00668   int number = 0;
00669   bool b = kspreadfunc_product_helper( context,
00670                                        context.value()->listValue(),
00671                                        result, number );
00672 
00673   if ( number == 0 )
00674     result = 0.0; // Excel specific
00675 
00676   if ( b )
00677     context.setValue( new KSValue( result ) );
00678 
00679   return b;
00680 }
00681 
00682 // Function: product
00683 bool kspreadfunc_kproduct( KSContext& context )
00684 {
00685   double result = 1.0;
00686   int number = 0;
00687   bool b = kspreadfunc_product_helper( context,
00688                                        context.value()->listValue(),
00689                                        result, number );
00690 
00691   if ( b )
00692     context.setValue( new KSValue( result ) );
00693 
00694   return b;
00695 }
00696 
00697 static int kspreadfunc_div_helper( KSContext & context,
00698                                    QValueList<KSValue::Ptr> & args,
00699                                    double & result )
00700 {
00701   QValueList<KSValue::Ptr>::Iterator it = args.begin();
00702   QValueList<KSValue::Ptr>::Iterator end = args.end();
00703 
00704   result = (*it)->doubleValue();
00705   ++it;
00706   int number = 0;
00707 
00708   for( ; it != end; ++it )
00709   {
00710     if ( KSUtil::checkType( context, *it, KSValue::ListType, false ) )
00711     {
00712       if ( !kspreadfunc_product_helper( context, (*it)->listValue(), result, number ) )
00713         return 0;
00714     }
00715     else if ( KSUtil::checkType( context, *it, KSValue::DoubleType, true ) )
00716     {
00717       double val =(*it)->doubleValue();
00718 
00719       if (val == 0)
00720         return -1;
00721 
00722       result /= val;
00723     }
00724   }
00725 
00726   return 1;
00727 }
00728 
00729 // Function: DIV
00730 bool kspreadfunc_div( KSContext& context )
00731 {
00732   double result = 0.0;
00733   int b = kspreadfunc_div_helper( context,
00734                                   context.value()->listValue(),
00735                                   result );
00736 
00737   if ( b == 1 )
00738     context.setValue( new KSValue( result ) );
00739   else if ( b == -1 )
00740     context.setValue( new KSValue( i18n("#DIV/0") ) );
00741   else
00742     return false;
00743 
00744   return true;
00745 }
00746 
00747 static bool kspreadfunc_sumsq_helper( KSContext& context, QValueList<KSValue::Ptr>& args, double& result )
00748 {
00749   QValueList<KSValue::Ptr>::Iterator it = args.begin();
00750   QValueList<KSValue::Ptr>::Iterator end = args.end();
00751 
00752   for( ; it != end; ++it )
00753   {
00754     if ( KSUtil::checkType( context, *it, KSValue::ListType, false ) )
00755     {
00756       if ( !kspreadfunc_sum_helper( context, (*it)->listValue(), result, false ) )
00757         return false;
00758     }
00759     else if ( KSUtil::checkType( context, *it, KSValue::DoubleType, true ) )
00760     {
00761       result += ((*it)->doubleValue()*(*it)->doubleValue());
00762     }
00763     else if ( !KSUtil::checkType( context, *it, KSValue::Empty, true ) )
00764       return false;
00765   }
00766 
00767   return true;
00768 }
00769 
00770 // Function: SUMSQ
00771 bool kspreadfunc_sumsq( KSContext& context )
00772 {
00773   double result = 0.0;
00774   bool b = kspreadfunc_sumsq_helper( context, context.value()->listValue(), result );
00775 
00776   if ( b )
00777     context.setValue( new KSValue( result ) );
00778 
00779   return b;
00780 }
00781 
00782 static bool kspreadfunc_max_helper( KSContext & context, QValueList<KSValue::Ptr> & args,
00783                                     double & result, int & inter, int mode )
00784 {
00785   QValueList<KSValue::Ptr>::Iterator it = args.begin();
00786   QValueList<KSValue::Ptr>::Iterator end = args.end();
00787 
00788   for( ; it != end; ++it )
00789   {
00790     if ( KSUtil::checkType( context, *it, KSValue::ListType, false ) )
00791     {
00792 
00793       if ( !kspreadfunc_max_helper( context, (*it)->listValue(), result, inter, mode ) )
00794         return false;
00795     }
00796     else if ( KSUtil::checkType( context, *it, KSValue::DoubleType, true ) )
00797     {
00798       if ( inter == 0 )
00799       {
00800         result = (*it)->doubleValue();
00801         inter  = 1;
00802       }
00803       if ( result < (*it)->doubleValue() )
00804         result = (*it)->doubleValue();
00805     }
00806     else if ( mode == 1 && KSUtil::checkType( context, *it, KSValue::BoolType, true ) )
00807     {
00808       double n = ( (*it)->boolValue() ? 1.0 : 0.0 );
00809       if ( inter == 0 )
00810       {
00811         result = n;
00812         inter = 1;
00813       }
00814       if ( result < n )
00815         result = n;
00816     }
00817   }
00818 
00819   return true;
00820 }
00821 
00822 // Function: MAX
00823 bool kspreadfunc_max( KSContext& context )
00824 {
00825   double result = 0.0;
00826 
00827   //init first element
00828   int inter=0;
00829 
00830   bool b = kspreadfunc_max_helper( context, context.value()->listValue(), result, inter, 0 );
00831 
00832   if ( b )
00833     context.setValue( new KSValue( result ) );
00834 
00835   return b;
00836 }
00837 
00838 // Function: MAXA
00839 bool kspreadfunc_maxa( KSContext & context )
00840 {
00841   double result = 0.0;
00842 
00843   //init first element
00844   int inter = 0;
00845 
00846   bool b = kspreadfunc_max_helper( context, context.value()->listValue(), result, inter, 1 );
00847 
00848   if ( b )
00849     context.setValue( new KSValue( result ) );
00850 
00851   return b;
00852 }
00853 
00854 static int kspreadfunc_gcd_gcd(int value1, int value2)
00855 {
00856   // start with the lower value.
00857   int n = (value1 <= value2 ? value1 : value2);
00858 
00859   // check if this is already the result
00860   if ((value1 % n == 0) && (value2 % n == 0))
00861   {
00862     return n;
00863   }
00864   // to save time: start with n = n / 2
00865   n = (int) (n / 2);
00866 
00867   while ((value1 % n != 0) || (value2 % n != 0))
00868   {
00869     --n;
00870   }
00871 
00872   return n;
00873 }
00874 
00875 static bool kspreadfunc_gcd_helper( KSContext & context,
00876                                     QValueList<KSValue::Ptr>& args,
00877                                     int & result)
00878 {
00879   QValueList<KSValue::Ptr>::Iterator it  = args.begin();
00880   QValueList<KSValue::Ptr>::Iterator end = args.end();
00881 
00882   // at first get the smallest value to start with
00883   for( ; it != end; ++it )
00884   {
00885     if ( KSUtil::checkType( context, *it, KSValue::ListType, false ) )
00886     {
00887       if ( !kspreadfunc_gcd_helper( context, (*it)->listValue(), result ) )
00888         return false;
00889     }
00890     else if ( KSUtil::checkType( context, *it, KSValue::IntType, true ) )
00891     {
00892       int val = (*it)->intValue();
00893 
00894       if (val == 0)
00895       {
00896         result = 0;
00897         return true;
00898       }
00899 
00900       if ((result == 0) || (val < result))
00901         result = val;
00902     }
00903   }
00904 
00905   it = args.begin();
00906 
00907   // calculate the LCD:
00908   for( ; it != end; ++it )
00909   {
00910     if ( KSUtil::checkType( context, *it, KSValue::ListType, false ) )
00911     {
00912       if ( !kspreadfunc_gcd_helper( context, (*it)->listValue(), result ) )
00913         return false;
00914     }
00915     else if ( KSUtil::checkType( context, *it, KSValue::IntType, true ) )
00916     {
00917       int n = kspreadfunc_gcd_gcd(result, (*it)->intValue());
00918 
00919       if (n != result)
00920       {
00921         result = n;
00922         it = args.begin();
00923 
00924         continue;
00925       }
00926     }
00927   }
00928 
00929   if (result < 0)
00930     result *= -1;
00931 
00932   context.setValue(new KSValue(result));
00933 
00934   return true;
00935 }
00936 
00937 // Function: GCD
00938 bool kspreadfunc_gcd( KSContext & context )
00939 {
00940   int result = 0;
00941 
00942   bool b = kspreadfunc_gcd_helper(context, context.value()->listValue(),
00943                   result);
00944 
00945   if (b)
00946     context.setValue(new KSValue(result));
00947 
00948   return b;
00949 }
00950 
00951 static bool kspreadfunc_lcm_helper( KSContext & context,
00952                     QValueList<KSValue::Ptr> & args,
00953                     double & result,
00954                     double & max,
00955                     double & inter,
00956                     int & signs)
00957 {
00958   // calculating the LCM:
00959   // algorithm: choose the biggest value in the list
00960   // take this as interval for increasing the numbers you check with
00961   // go through the list, check every value if your proposal is a multiple
00962   // if not, increase your proposal value and start again.
00963 
00964   // when you have found your LCM: check if it has the right sign:
00965   // if the number of (-) signs in the list is , the result is positive
00966   // otherwise negative.
00967 
00968   QValueList<KSValue::Ptr>::Iterator it  = args.begin();
00969   QValueList<KSValue::Ptr>::Iterator end = args.end();
00970 
00971   // first loop: check for the biggest value
00972   // and count number of (-) signs:
00973   for (; it != end; ++it)
00974   {
00975     if (KSUtil::checkType(context, *it, KSValue::ListType, false))
00976     {
00977       if (!kspreadfunc_lcm_helper(context, (*it)->listValue(), result, max, inter, signs))
00978         return false;
00979     }
00980     else if (KSUtil::checkType(context, *it, KSValue::DoubleType, true))
00981     {
00982       double d = (double) (*it)->doubleValue();
00983 
00984       if (d < 0)
00985     ++signs;
00986 
00987       if (result < d)
00988     result = d;
00989     }
00990   }
00991 
00992   inter = result;
00993   it    = args.begin();
00994 
00995   while (true)
00996   {
00997     if (KSUtil::checkType(context, *it, KSValue::ListType, false))
00998     {
00999       if (!kspreadfunc_lcm_helper( context, (*it)->listValue(), result, max, inter, signs))
01000     return false;
01001     }
01002     else if (KSUtil::checkType(context, *it, KSValue::DoubleType, true))
01003     {
01004       double d = inter / (*it)->doubleValue();
01005 
01006       // if it is not a multiple, increase you proposal value and start again
01007       if (!approx_equal(d, floor(d)))
01008       {
01009     inter += result;
01010 
01011     it = args.begin();
01012     continue;
01013       }
01014     } // end else if
01015 
01016     // ... otherwise check the next value if any
01017     ++it;
01018 
01019     if (it == end)
01020       break;
01021   }
01022 
01023   result = inter;
01024 
01025   // check if we have the correct sign (-/+)
01026   if (signs > 0)
01027   {
01028     if ((result < 0) && (signs % 2 == 0))
01029       result *= -1;
01030     else if ((result > 0) && (signs % 2 != 0))
01031       result *= -1;
01032   }
01033 
01034   return true;
01035 }
01036 
01037 // Function: lcm
01038 bool kspreadfunc_lcm( KSContext & context )
01039 {
01040   double result = 0.0;
01041   double max    = 1.0;
01042   double inter  = 0.0;
01043   int    signs  = 0;
01044 
01045   bool b = kspreadfunc_lcm_helper(context, context.value()->listValue(),
01046                   result, max, inter, signs);
01047 
01048   if (b)
01049     context.setValue(new KSValue(result));
01050 
01051   return b;
01052 
01053 }
01054 
01055 static bool kspreadfunc_min_helper( KSContext & context, QValueList<KSValue::Ptr> & args,
01056                                     double & result, int & inter, int mode )
01057 {
01058   QValueList<KSValue::Ptr>::Iterator it = args.begin();
01059   QValueList<KSValue::Ptr>::Iterator end = args.end();
01060 
01061   for ( ; it != end; ++it )
01062   {
01063     if ( KSUtil::checkType( context, *it, KSValue::ListType, false ) )
01064     {
01065 
01066       if ( !kspreadfunc_min_helper( context, (*it)->listValue(), result, inter, mode ) )
01067         return false;
01068     }
01069     else if ( KSUtil::checkType( context, *it, KSValue::DoubleType, true ) )
01070     {
01071       if ( inter == 0 )
01072       {
01073         result = (*it)->doubleValue();
01074         inter  = 1;
01075       }
01076       if ( result > (*it)->doubleValue() )
01077         result = (*it)->doubleValue();
01078     }
01079     else if ( mode == 1 && KSUtil::checkType( context, *it, KSValue::BoolType, true ) )
01080     {
01081       double n = ( (*it)->boolValue() ? 1.0 : 0.0 );
01082       if ( inter == 0 )
01083       {
01084         result = n;
01085         inter  = 1;
01086       }
01087       if ( result > n )
01088         result = n;
01089     }
01090   }
01091 
01092   return true;
01093 }
01094 
01095 // Function: MIN
01096 bool kspreadfunc_min( KSContext& context )
01097 {
01098   double result = 0.0;
01099 
01100   //init first element
01101   int inter = 0;
01102 
01103   bool b = kspreadfunc_min_helper( context, context.value()->listValue(), result, inter, 0 );
01104 
01105   if ( b )
01106     context.setValue( new KSValue( result ) );
01107 
01108   return b;
01109 }
01110 
01111 // Function: MINA
01112 bool kspreadfunc_mina( KSContext& context )
01113 {
01114   double result = 0.0;
01115 
01116   //init first element
01117   int inter = 0;
01118 
01119   bool b = kspreadfunc_min_helper( context, context.value()->listValue(), result, inter, 1 );
01120 
01121   if ( b )
01122     context.setValue( new KSValue( result ) );
01123 
01124   return b;
01125 }
01126 
01127 static bool kspreadfunc_mult_helper( KSContext& context, QValueList<KSValue::Ptr>& args, double& result )
01128 {
01129   QValueList<KSValue::Ptr>::Iterator it = args.begin();
01130   QValueList<KSValue::Ptr>::Iterator end = args.end();
01131 
01132   for( ; it != end; ++it )
01133   {
01134     if ( KSUtil::checkType( context, *it, KSValue::ListType, false ) )
01135     {
01136       if ( !kspreadfunc_mult_helper( context, (*it)->listValue(), result ) )
01137         return false;
01138     }
01139     else if ( KSUtil::checkType( context, *it, KSValue::DoubleType, true ) )
01140       result *= (*it)->doubleValue();
01141   }
01142 
01143   return true;
01144 }
01145 
01146 // Function: MULT
01147 bool kspreadfunc_mult( KSContext& context )
01148 {
01149   double result = 1.0;
01150   bool b = kspreadfunc_mult_helper( context, context.value()->listValue(), result );
01151 
01152   if ( b )
01153     context.setValue( new KSValue( result ) );
01154 
01155   return b;
01156 }
01157 
01158 // Function: INT
01159 bool kspreadfunc_int( KSContext& context )
01160 {
01161   QValueList<KSValue::Ptr>& args = context.value()->listValue();
01162 
01163   if ( !KSUtil::checkArgumentsCount( context, 1, "INT", true ) )
01164     return false;
01165   double val=0.0;
01166   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01167     {
01168     if(!KSUtil::checkType( context, args[0], KSValue::Empty, true ) )
01169       return false;
01170     }
01171   else
01172     val=args[0]->doubleValue();
01173 
01174   context.setValue( new KSValue( floor( val ) ) );
01175   return true;
01176 }
01177 
01178 // Function: QUOTIENT
01179 bool kspreadfunc_quotient( KSContext& context )
01180 {
01181   QValueList<KSValue::Ptr>& args = context.value()->listValue();
01182 
01183   if ( !KSUtil::checkArgumentsCount( context, 2, "QUOTIENT", true ) )
01184     return false;
01185 
01186   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01187     return false;
01188 
01189   if ( !KSUtil::checkType( context, args[1], KSValue::DoubleType, true ) )
01190     return false;
01191 
01192   double num = args[0]->doubleValue();
01193   double den = args[1]->doubleValue();
01194 
01195   if( den == 0 ) return false;
01196 
01197   context.setValue( new KSValue( (int)(num/den) ) );
01198   return true;
01199 }
01200 
01201 
01202 // Function: eps
01203 bool kspreadfunc_eps( KSContext& context )
01204 {
01205 // #### This should adjust according to the actual number system used (float, double, long double, ...)
01206     if( !KSUtil::checkArgumentsCount( context, 0, "eps", true ) )
01207       return false;
01208 
01209     context.setValue( new KSValue(DBL_EPSILON));
01210     return true;
01211 }
01212 
01213 bool kspreadfunc_randexp( KSContext & context )
01214 {
01215   QValueList<KSValue::Ptr> & args = context.value()->listValue();
01216 
01217   if ( !KSUtil::checkArgumentsCount( context, 1, "RANDEXP", true ) )
01218     return false;
01219 
01220   if( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01221     return false;
01222 
01223   double d = args[0]->doubleValue();
01224 
01225   d = -1 * d * log( (double) rand() / ( RAND_MAX + 1.0 ) );
01226 
01227   context.setValue( new KSValue( d ) );
01228   return true;
01229 }
01230 
01231 bool kspreadfunc_randbinom( KSContext & context )
01232 {
01233   QValueList<KSValue::Ptr> & args = context.value()->listValue();
01234 
01235   if ( !KSUtil::checkArgumentsCount( context, 2, "RANDBINOM", true ) )
01236     return false;
01237 
01238   if( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01239     return false;
01240   if( !KSUtil::checkType( context, args[1], KSValue::IntType, true ) )
01241     return false;
01242 
01243   double d  = args[0]->doubleValue();
01244   int    tr = args[1]->intValue();
01245 
01246   if ( d < 0 || d > 1 )
01247     return false;
01248 
01249   if ( tr < 0 )
01250     return false;
01251 
01252   // taken from gnumeric
01253   double x = pow(1 - d, tr);
01254   double r = (double) rand() / ( RAND_MAX + 1.0 );
01255   double t = x;
01256   double i = 0;
01257 
01258   while (r > t)
01259   {
01260     x *= (((tr - i) * d) / ((1 + i) * (1 - d)));
01261     i += 1;
01262     t += x;
01263   }
01264 
01265   context.setValue( new KSValue( i ) );
01266   return true;
01267 }
01268 
01269 bool kspreadfunc_randnegbinom( KSContext & context )
01270 {
01271   QValueList<KSValue::Ptr> & args = context.value()->listValue();
01272 
01273   if ( !KSUtil::checkArgumentsCount( context, 2, "RANDNEGBINOM", true ) )
01274     return false;
01275 
01276   if( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01277     return false;
01278   if( !KSUtil::checkType( context, args[1], KSValue::IntType, true ) )
01279     return false;
01280 
01281   double d = args[0]->doubleValue();
01282   int    f = args[1]->intValue();
01283 
01284   if ( d < 0 || d > 1 )
01285     return false;
01286 
01287   if ( f < 0 )
01288     return false;
01289 
01290   // taken from Gnumeric
01291   double x = pow(d, f);
01292   double r = (double) rand() / ( RAND_MAX + 1.0 );
01293   double t = x;
01294   double i = 0;
01295 
01296   while (r > t)
01297   {
01298     x *= ( ( ( f + i ) * ( 1 - d ) ) / (1 + i) ) ;
01299     i += 1;
01300     t += x;
01301   }
01302 
01303   context.setValue( new KSValue( i ) );
01304   return true;
01305 }
01306 
01307 bool kspreadfunc_randbernoulli( KSContext & context )
01308 {
01309   QValueList<KSValue::Ptr> & args = context.value()->listValue();
01310 
01311   if ( !KSUtil::checkArgumentsCount( context, 1, "RANDBERNOULLI", true ) )
01312     return false;
01313 
01314   if( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01315     return false;
01316 
01317   double d = args[0]->doubleValue();
01318   if ( d < 0 || d > 1 )
01319     return false;
01320 
01321   // taken from Gnumeric
01322   double r = (double) rand() / ( RAND_MAX + 1.0 );
01323 
01324   context.setValue( new KSValue( ( r <= d ) ? 1.0 : 0.0 ) );
01325   return true;
01326 }
01327 
01328 bool kspreadfunc_randnorm( KSContext & context )
01329 {
01330   QValueList<KSValue::Ptr> & args = context.value()->listValue();
01331 
01332   if ( !KSUtil::checkArgumentsCount( context, 2, "RANDNORM", true ) )
01333     return false;
01334 
01335   if( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01336     return false;
01337   if( !KSUtil::checkType( context, args[1], KSValue::DoubleType, true ) )
01338     return false;
01339 
01340   double mu = args[0]->doubleValue();
01341   double sigma = args[1]->doubleValue();
01342 
01343   //using polar form of the Box-Muller transformation
01344   //refer to http://www.taygeta.com/random/gaussian.html for more info
01345 
01346   double x1, x2, w;
01347   do {
01348     x1 = (double) rand() / (RAND_MAX + 1.0);
01349     x2 = (double) rand() / (RAND_MAX + 1.0);
01350     x1 = 2.0 * x1 - 1.0;
01351     x2 = 2.0 * x2 - 1.0;
01352     w = x1 * x1 + x2 * x2;
01353   } while (w >= 1.0);
01354 
01355   w = sqrt ((-2.0 * log (w)) / w);
01356   double res = x1 * w;
01357 
01358   res = res * sigma + mu;
01359   context.setValue( new KSValue( res ) );
01360   return true;
01361 }
01362 
01363 bool kspreadfunc_randpoisson( KSContext & context )
01364 {
01365   QValueList<KSValue::Ptr> & args = context.value()->listValue();
01366 
01367   if ( !KSUtil::checkArgumentsCount( context, 1, "RANDPOISSON", true ) )
01368     return false;
01369 
01370   if( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01371     return false;
01372 
01373   double d = args[0]->doubleValue();
01374   if ( d < 0 )
01375     return false;
01376 
01377   // taken from Gnumeric...
01378   double x = exp( -1 * d );
01379   double r = ( double ) rand() / ( RAND_MAX + 1.0 );
01380   double t = x;
01381   double i = 0;
01382 
01383   while ( r > t )
01384   {
01385     x *= d / ( i + 1 );
01386     i += 1;
01387     t += x;
01388   }
01389 
01390   context.setValue( new KSValue( i ) );
01391   return true;
01392 }
01393 
01394 // Function: rand
01395 bool kspreadfunc_rand( KSContext& context )
01396 {
01397     // QValueList<KSValue::Ptr>& args = context.value()->listValue();
01398 
01399     if ( !KSUtil::checkArgumentsCount( context, 0, "rand", true ) )
01400       return false;
01401 
01402     context.setValue( new KSValue((double) rand()/(RAND_MAX + 1.0)));
01403     return true;
01404 }
01405 
01406 // Function: RANDBETWEEN
01407 bool kspreadfunc_randbetween( KSContext& context )
01408 {
01409     QValueList<KSValue::Ptr>& args = context.value()->listValue();
01410 
01411     if ( !KSUtil::checkArgumentsCount( context, 2, "RANDBETWEEN", true ) )
01412       return false;
01413     if ( !KSUtil::checkType( context, args[0], KSValue::IntType, true ) )
01414         return false;
01415     if( !KSUtil::checkType( context, args[1], KSValue::IntType, true ) )
01416         return false;
01417     if(args[0]->intValue()>args[1]->intValue())
01418         {
01419         context.setValue( new KSValue(i18n("Err")));
01420         return true;
01421         }
01422 
01423     context.setValue( new KSValue((double)(((double)args[1]->intValue()-(double)args[0]->intValue())*rand()/RAND_MAX+((double)args[0]->intValue()))));
01424 
01425     return true;
01426 }
01427 
01428 // Function: POW
01429 bool kspreadfunc_pow( KSContext& context )
01430 {
01431   QValueList<KSValue::Ptr>& args = context.value()->listValue();
01432 
01433   if ( !KSUtil::checkArgumentsCount( context, 2, "pow",true ) )
01434     return false;
01435 
01436   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01437     return false;
01438 
01439   if ( !KSUtil::checkType( context, args[1], KSValue::DoubleType, true ) )
01440     return false;
01441 
01442   context.setValue( new KSValue( pow( args[0]->doubleValue(),args[1]->doubleValue() ) ) );
01443 
01444   return true;
01445 }
01446 
01447 // Function: MOD
01448 bool kspreadfunc_mod( KSContext& context )
01449 {
01450   double result=0;
01451   QValueList<KSValue::Ptr>& args = context.value()->listValue();
01452 
01453   if ( !KSUtil::checkArgumentsCount( context, 2, "MOD",true ) )
01454     return false;
01455 
01456   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01457     return false;
01458 
01459   if ( !KSUtil::checkType( context, args[1], KSValue::DoubleType, true ) )
01460     return false;
01461   if( (int)args[1]->doubleValue()!=0)
01462   {
01463         result=(int)args[0]->doubleValue() % (int)args[1]->doubleValue();
01464         if( result < 0 ) result += (int)args[1]->doubleValue();
01465         context.setValue( new KSValue(  result  ) );
01466   }
01467   else
01468   {
01469         context.setValue( new KSValue( i18n("#DIV/0") ) );
01470 
01471   }
01472   return true;
01473 }
01474 
01475 // Function: fact
01476 bool kspreadfunc_fact( KSContext& context )
01477 {
01478   double result;
01479   QString tmp;
01480   QValueList<KSValue::Ptr>& args = context.value()->listValue();
01481 
01482   if ( !KSUtil::checkArgumentsCount( context,1, "fact",true ) )
01483     return false;
01484 
01485   if ( !KSUtil::checkType( context, args[0], KSValue::IntType, true ) )
01486     return false;
01487 
01488   result=util_fact((double)args[0]->intValue(),0);
01489   //In util_fact function val must be positive
01490   tmp=i18n("Err");
01491   if(result==-1)
01492         context.setValue( new KSValue(tmp));
01493   else
01494         context.setValue( new KSValue(result ));
01495 
01496   return true;
01497 }
01498 
01499 // Function: FACTDOUBLE
01500 bool kspreadfunc_factdouble( KSContext& context )
01501 {
01502   QValueList<KSValue::Ptr>& args = context.value()->listValue();
01503 
01504   if ( !KSUtil::checkArgumentsCount( context, 1, "FACTDOUBLE",true ) )
01505     return false;
01506 
01507   if ( !KSUtil::checkType( context, args[0], KSValue::IntType, true ) )
01508     return false;
01509 
01510   int number = args[0]->intValue();
01511   if( number < 0 )
01512     return false;
01513 
01514   double result = 1;
01515   for( int n = number; n > 0; n -= 2 )
01516     result *= n;
01517 
01518   context.setValue( new KSValue( result ) );
01519 
01520   return true;
01521 }
01522 
01523 // Function: MULTINOMIAL
01524 bool kspreadfunc_multinomial( KSContext& context )
01525 {
01526   QValueList<KSValue::Ptr>& args = context.value()->listValue();
01527 
01528   QValueList<KSValue::Ptr>::Iterator it = args.begin();
01529   QValueList<KSValue::Ptr>::Iterator end = args.end();
01530 
01531   double num = 0, den = 1;
01532 
01533   for( ; it != end; ++it )
01534   {
01535     if ( KSUtil::checkType( context, *it, KSValue::IntType, false ) )
01536     {
01537       int val = (*it)->intValue();
01538       if( val < 0 ) return false;
01539       num += val;
01540       den *= util_fact( val, 0 );
01541     }
01542   }
01543 
01544   num = util_fact( num, 0 );
01545   double result = num / den;
01546 
01547   context.setValue( new KSValue( result ) );
01548   return true;
01549 }
01550 
01551 // Function: sign
01552 bool kspreadfunc_sign( KSContext& context )
01553 {
01554   int value=0;
01555   QValueList<KSValue::Ptr>& args = context.value()->listValue();
01556 
01557   if ( !KSUtil::checkArgumentsCount( context, 1, "sign", true ) )
01558     return false;
01559   double val=0.0;
01560   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01561     {
01562       if ( !KSUtil::checkType( context, args[0], KSValue::Empty, true ) )
01563     return false;
01564     }
01565   val=args[0]->doubleValue();
01566 
01567   if(val>0)
01568     value=1;
01569   else if(val<0)
01570     value=-1;
01571   else if(val==0)
01572     value=0;
01573 
01574   context.setValue( new KSValue( value ) );
01575 
01576   return true;
01577 }
01578 
01579 // Function: INV
01580 bool kspreadfunc_inv( KSContext& context )
01581 {
01582   QValueList<KSValue::Ptr>& args = context.value()->listValue();
01583 
01584   if ( !KSUtil::checkArgumentsCount( context, 1, "INV",true ) )
01585     return false;
01586   double val=0.0;
01587   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01588     {
01589       if ( !KSUtil::checkType( context, args[0], KSValue::Empty, true ) )
01590     return false;
01591     }
01592   val=args[0]->doubleValue();
01593 
01594 
01595   context.setValue( new KSValue( val*(-1) ) );
01596 
01597   return true;
01598 }
01599 
01600 bool kspreadfunc_mround( KSContext& context )
01601 {
01602   QValueList<KSValue::Ptr>& args = context.value()->listValue();
01603 
01604   if ( !KSUtil::checkArgumentsCount( context, 2, "MROUND", true ) )
01605     return false;
01606 
01607   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01608     return false;
01609   if ( !KSUtil::checkType( context, args[1], KSValue::DoubleType, true ) )
01610     return false;
01611 
01612   double d = args[0]->doubleValue();
01613   double m = args[1]->doubleValue();
01614 
01615   if ( ( d > 0 && m < 0 )
01616       || ( d < 0 && m > 0 ) )
01617     return false;
01618 
01619   int sign = 1;
01620 
01621   if ( d < 0 )
01622   {
01623     sign = -1;
01624     d = -d;
01625     m = -m;
01626   }
01627 
01628   // from gnumeric:
01629   double mod = fmod( d, m );
01630   double div = d - mod;
01631 
01632   double accuracyLimit = 0.0000003;
01633   double result = sign * ( div + ( ( mod + accuracyLimit >= m / 2 ) ? m : 0 ) );
01634 
01635   context.setValue( new KSValue( result ) );
01636   return true;
01637 }
01638 
01639 // Function: ROUNDDOWN
01640 bool kspreadfunc_rounddown( KSContext& context )
01641 {
01642   QValueList<KSValue::Ptr>& args = context.value()->listValue();
01643   double result=0;
01644   int digits=0;
01645   if ( !KSUtil::checkArgumentsCount( context, 2, "ROUNDDOWN", true ) )
01646   {
01647         //just 1 argument => number of decimal =0 by default
01648         if ( !KSUtil::checkArgumentsCount( context, 1, "ROUNDDOWN", true ) )
01649                 return false;
01650         if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01651             return false;
01652         digits=0;
01653   }
01654   else
01655   {
01656         if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01657                 return false;
01658         if ( !KSUtil::checkType( context, args[1], KSValue::IntType, true ) )
01659                 return false;
01660         digits=args[1]->intValue();
01661   }
01662   result=args[0]->doubleValue()*pow(10.0, digits);
01663   context.setValue( new KSValue( floor( result )/pow(10.0, digits) ) );
01664 
01665   return true;
01666 }
01667 
01668 // Function: ROUNDUP
01669 bool kspreadfunc_roundup( KSContext& context )
01670 {
01671   QValueList<KSValue::Ptr>& args = context.value()->listValue();
01672   double result=0;
01673   int digits=0;
01674   if ( !KSUtil::checkArgumentsCount( context, 2, "ROUNDUP", true ) )
01675   {
01676         //just 1 argument => number of decimal =0 by default
01677         if ( !KSUtil::checkArgumentsCount( context, 1, "ROUNDUP", true ) )
01678                 return false;
01679         if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01680             return false;
01681         digits=0;
01682   }
01683   else
01684   {
01685         if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01686                 return false;
01687         if ( !KSUtil::checkType( context, args[1], KSValue::IntType, true ) )
01688                 return false;
01689         digits=args[1]->intValue();
01690   }
01691   // This is not correct solution for problem with floating point numbers and probably
01692   // will fail in platforms where float and double lenghts are same.
01693   if (approx_equal(floor(args[0]->doubleValue()*::pow(10,digits)), args[0]->doubleValue()*::pow(10,digits)))
01694       result = args[0]->doubleValue();
01695   else
01696       result=floor(args[0]->doubleValue()*::pow(10,digits)+1)/::pow(10,digits);
01697   context.setValue( new KSValue( result) );
01698 
01699   return true;
01700 }
01701 
01702 // Function: ROUND
01703 bool kspreadfunc_round( KSContext& context )
01704 {
01705   QValueList<KSValue::Ptr>& args = context.value()->listValue();
01706   double result=0;
01707   int digits=0;
01708   if ( !KSUtil::checkArgumentsCount( context, 2, "ROUND", true ) )
01709         {
01710         //just 1 argument => number of decimal =0 by default
01711         if ( !KSUtil::checkArgumentsCount( context, 1, "ROUND", true ) )
01712                 return false;
01713         if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01714             return false;
01715         digits=0;
01716         }
01717   else
01718         {
01719         if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01720                 return false;
01721         if ( !KSUtil::checkType( context, args[1], KSValue::IntType, true ) )
01722                 return false;
01723         digits=args[1]->intValue();
01724         }
01725   result=floor(args[0]->doubleValue()*pow(10.0,digits)+0.5)/pow(10.0,digits);
01726   context.setValue( new KSValue( result) );
01727 
01728   return true;
01729 }
01730 
01731 // Function: EVEN
01732 bool kspreadfunc_even( KSContext& context )
01733 {
01734   QValueList<KSValue::Ptr>& args = context.value()->listValue();
01735   if ( !KSUtil::checkArgumentsCount( context,1, "EVEN",true ) )
01736     return false;
01737 
01738   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01739     return false;
01740   double result;
01741   double val=args[0]->doubleValue();
01742   int sign=1;
01743   if(val<0)
01744         {
01745         sign=-1;
01746         val=-val;
01747         }
01748   if (approx_equal(val, floor(val)))
01749     val = floor(val);
01750  double valsup=ceil( val );
01751  if(fmod(valsup,2.0)==0)
01752         {
01753         if(val>valsup)
01754                 result=(int)(sign*(valsup+2));
01755         else
01756                 result=(int)(sign*valsup);
01757         }
01758  else
01759         {
01760         result=(int)(sign*(valsup+1));
01761         }
01762   context.setValue( new KSValue(result));
01763 
01764   return true;
01765 }
01766 
01767 // Function: ODD
01768 bool kspreadfunc_odd( KSContext& context )
01769 {
01770   QValueList<KSValue::Ptr>& args = context.value()->listValue();
01771   if ( !KSUtil::checkArgumentsCount( context,1, "ODD",true ) )
01772     return false;
01773 
01774   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01775     return false;
01776   double result;
01777   double valsup;
01778   int sign=1;
01779   double val= args[0]->doubleValue();
01780   if (val < 0)
01781         {
01782         sign = -1;
01783         val = -val;
01784         }
01785   if (approx_equal(val, floor(val)))
01786     val = floor(val);
01787   valsup = ceil(val);
01788   if (fmod(valsup, 2.0) == 1)
01789         {
01790         if (val > valsup)
01791                 result=(int) (sign * (valsup + 2));
01792         else
01793                 result=(int) (sign * valsup);
01794         }
01795   else
01796         result=(int) (sign * (valsup + 1));
01797 
01798  context.setValue( new KSValue(result));
01799 
01800   return true;
01801 }
01802 
01803 static bool kspreadfunc_count_helper( KSContext& context, QValueList<KSValue::Ptr> & args, double & result )
01804 {
01805   QValueList<KSValue::Ptr>::Iterator it  = args.begin();
01806   QValueList<KSValue::Ptr>::Iterator end = args.end();
01807 
01808   for( ; it != end; ++it )
01809   {
01810     if ( KSUtil::checkType( context, *it, KSValue::ListType, false ) )
01811     {
01812       if ( !kspreadfunc_count_helper( context, (*it)->listValue(), result ) )
01813         return false;
01814     }
01815     else if ( KSUtil::checkType( context, *it, KSValue::DoubleType, true ) )
01816     {
01817     ++result;
01818     }
01819   }
01820 
01821   return true;
01822 }
01823 
01824 bool kspreadfunc_trunc( KSContext & context )
01825 {
01826   QValueList<KSValue::Ptr>& args = context.value()->listValue();
01827   int precision = 0;
01828 
01829   if( KSUtil::checkArgumentsCount( context, 2, "TRUNC", false ) )
01830   {
01831     if( !KSUtil::checkType( context, args[1], KSValue::IntType, true ) )
01832       return false;
01833 
01834     precision = args[1]->intValue();
01835   }
01836   else
01837   {
01838     if ( !KSUtil::checkArgumentsCount( context, 1, "TRUNC", true ) )
01839       return false;
01840   }
01841 
01842   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01843     return false;
01844 
01845   double result = args[0]->doubleValue();
01846 
01847   // TRUNC(254;-2) is 200
01848   if( precision < 0 )
01849   {
01850       precision = -precision;
01851       result = floor( result/pow(10.0,precision) ) * pow(10.0,precision);
01852       precision = 0;
01853   }
01854 
01855   int factor = (int) pow( 10.0, precision );
01856 
01857   result = floor( result * factor ) / factor;
01858 
01859   context.setValue( new KSValue( result ) );
01860 
01861   return true;
01862 }
01863 
01864 // Function: COUNT
01865 bool kspreadfunc_count( KSContext& context )
01866 {
01867   double result = 0.0;
01868 
01869   bool b = kspreadfunc_count_helper( context, context.value()->listValue(), result );
01870 
01871   if ( b )
01872     context.setValue( new KSValue( result ) );
01873 
01874   return b;
01875 }
01876 
01877 static bool kspreadfunc_counta_helper( KSContext& context, QValueList<KSValue::Ptr> & args,
01878                                        QValueList<KSValue::Ptr> & extra, int & resultA )
01879 {
01880   QValueList<KSValue::Ptr>::Iterator eit  = extra.begin();
01881   QValueList<KSValue::Ptr>::Iterator eend = extra.end();
01882 
01883   QValueList<KSValue::Ptr>::Iterator it  = args.begin();
01884 
01885   KSpreadMap * map = ((KSpreadInterpreter *) context.interpreter() )->document()->map();
01886   KSpreadSheet * sheet = ((KSpreadInterpreter *) context.interpreter() )->sheet();
01887   KSpreadSheet * t = 0;
01888   KSpreadCell * cell = 0;
01889 
01890   for ( ; eit != eend; ++eit )
01891   {
01892     int right = 0;
01893     int left = 0;
01894     int bottom = 0;
01895     int top = 0;
01896     if ( KSUtil::checkType( context, *eit, KSValue::StringType, true ) )
01897     {
01898       KSpreadRange range( (*eit)->stringValue(), map );
01899       if ( range.range.left() <= 0 || range.range.right() <= 0 )
01900       {
01901         KSpreadPoint point( (*eit)->stringValue(), map );
01902         if ( point.pos.x() <= 0 || point.pos.y() <= 0 )
01903           return false;
01904 
01905         right  = point.pos.x();
01906         bottom = point.pos.y();
01907         left   = right;
01908         top    = bottom;
01909 
01910         if ( !point.isSheetKnown() )
01911           t = sheet;
01912         else
01913           t = point.sheet;
01914       }
01915       else
01916       {
01917         right  = range.range.right();
01918         bottom = range.range.bottom();
01919         left   = range.range.left();
01920         top    = range.range.top();
01921 
01922         if ( !range.isSheetKnown() )
01923           t = sheet;
01924         else
01925           t = range.sheet;
01926       }
01927 
01928       for ( int x = left; x <= right; ++x )
01929       {
01930         for ( int y = top; y <= bottom; ++y )
01931         {
01932           kdDebug() << "Cell: " << x << ", " << y << endl;
01933           cell = t->cellAt( x, y );
01934           if ( !cell->isDefault() && !cell->isEmpty() )
01935           {
01936             if ( !cell->strOutText().isEmpty() )
01937               ++resultA;
01938           }
01939         }
01940       }
01941     }
01942     else if ( KSUtil::checkType( context, *it, KSValue::StringType, true ) )
01943     {
01944       kdDebug() << "String value" << endl;
01945       if ( !(*it)->stringValue().isEmpty() )
01946         ++resultA;
01947     }
01948     else if ( !KSUtil::checkType( context, *it, KSValue::Empty, true ) )
01949     {
01950       kdDebug() << "Empty" << endl;
01951       ++resultA;
01952     }
01953 
01954     ++it;
01955   }
01956 
01957   return true;
01958 }
01959 
01960 // Function: COUNTA
01961 bool kspreadfunc_counta( KSContext& context )
01962 {
01963   int resultA = 0;
01964 
01965   bool b = kspreadfunc_counta_helper( context, context.value()->listValue(),
01966                                       context.extraData()->listValue(), resultA );
01967 
01968   if ( b )
01969     context.setValue( new KSValue( resultA ) );
01970 
01971   return b;
01972 }
01973 
01974 static bool kspreadfunc_countblank_helper( KSContext& context, QValueList<KSValue::Ptr> & args,
01975                                            int & result )
01976 {
01977   KSpreadMap   * map   = ((KSpreadInterpreter *) context.interpreter() )->document()->map();
01978   KSpreadSheet * sheet = ((KSpreadInterpreter *) context.interpreter() )->sheet();
01979   KSpreadCell  * cell  = 0;
01980   KSpreadSheet * t     = 0;
01981 
01982   QValueList<KSValue::Ptr>::Iterator it  = args.begin();
01983   QValueList<KSValue::Ptr>::Iterator end = args.end();
01984 
01985   kdDebug() << "Result: " << result << endl;
01986 
01987   for( ; it != end; ++it )
01988   {
01989     if ( KSUtil::checkType( context, *it, KSValue::StringType, false ) )
01990     {
01991       kdDebug() << "S:" << (*it)->stringValue() << endl;
01992       int right = 0;
01993       int left = 0;
01994       int bottom = 0;
01995       int top = 0;
01996 
01997       KSpreadRange range( (*it)->stringValue(), map );
01998       if ( range.range.left() <= 0 || range.range.right() <= 0 )
01999       {
02000         KSpreadPoint point( (*it)->stringValue(), map );
02001 
02002         if ( point.pos.x() <= 0 || point.pos.y() <= 0 )
02003           continue; // not blank, whatever it is...
02004 
02005         right  = point.pos.x();
02006         bottom = point.pos.y();
02007         left   = right;
02008         top    = bottom;
02009 
02010         if ( !point.isSheetKnown() )
02011           t = sheet;
02012         else
02013           t = point.sheet;
02014       }
02015       else
02016       {
02017         right  = range.range.right();
02018         bottom = range.range.bottom();
02019         left   = range.range.left();
02020         top    = range.range.top();
02021 
02022         if ( !range.isSheetKnown() )
02023           t = sheet;
02024         else
02025           t = range.sheet;
02026       }
02027 
02028       for ( int x = left; x <= right; ++x )
02029       {
02030         for ( int y = top; y <= bottom; ++y )
02031         {
02032           kdDebug() << "Cell: " << x << ", " << y << endl;
02033           cell = t->cellAt( x, y );
02034           if ( cell->isDefault() || cell->isEmpty() || cell->strOutText().isEmpty() )
02035           {
02036             ++result;
02037           }
02038         }
02039       }
02040     }
02041   }
02042 
02043   kdDebug() << "Result 2: " << result << endl;
02044 
02045   return true;
02046 }
02047 
02048 // Function: COUNTBLANK
02049 bool kspreadfunc_countblank( KSContext& context )
02050 {
02051   int result = 0;
02052 
02053   kdDebug() << "Countblank: " << endl;
02054 
02055   bool b = kspreadfunc_countblank_helper( context, context.extraData()->listValue(), result );
02056 
02057   if ( b )
02058     context.setValue( new KSValue( result ) );
02059 
02060   return b;
02061 }
02062 
02063 static int kspreadfunc_countif_helper( KSContext& context, KSValue *value,
02064                                        const QString &criteria )
02065 {
02066   if( KSUtil::checkType( context, value, KSValue::DoubleType, false ) )
02067   {
02068     KSpreadDB::Condition cond;
02069     getCond( cond, criteria );
02070 
02071     return conditionMatches( cond, value->doubleValue() ) ? 1 : 0;
02072   }
02073 
02074   if( KSUtil::checkType( context, value, KSValue::StringType, false ) )
02075   {
02076     KSpreadDB::Condition cond;
02077     getCond( cond, criteria );
02078 
02079     return conditionMatches( cond, value->stringValue() ) ? 1 : 0;
02080   }
02081 
02082   if( KSUtil::checkType( context, value, KSValue::BoolType, false ) )
02083   {
02084     bool criteria_bool = criteria.lower() == "true";
02085     if( !value && (criteria.lower() != "false") ) return 0;
02086     return criteria_bool == value->boolValue() ? 1 : 0;
02087   }
02088 
02089   if( KSUtil::checkType( context, value, KSValue::ListType, false ) )
02090   {
02091     QValueList<KSValue::Ptr>& args = value->listValue();
02092     QValueList<KSValue::Ptr>::Iterator it = args.begin();
02093     QValueList<KSValue::Ptr>::Iterator end = args.end();
02094 
02095     int count = 0;
02096     for( ; it != end; ++it )
02097        if ( !kspreadfunc_countif_helper( context, *it, criteria ) ) count++;
02098 
02099     return count;
02100   }
02101 
02102   return 0;
02103 }
02104 
02105 // Function: COUNTIF
02106 bool kspreadfunc_countif( KSContext& context )
02107 {
02108   QValueList<KSValue::Ptr>& args = context.value()->listValue();
02109 
02110   if ( !KSUtil::checkArgumentsCount( context, 2, "COUNTIF", true ) )
02111     return false;
02112 
02113   if ( !KSUtil::checkType( context, args[1], KSValue::StringType, true ) )
02114     return false;
02115 
02116   KSValue* value = args[0];
02117   QString criteria = args[1]->stringValue();
02118 
02119   int result = kspreadfunc_countif_helper( context, value, criteria );
02120 
02121   context.setValue( new KSValue( result ) );
02122   return true;
02123 }
02124 
02125 // Function: FIB
02126 bool kspreadfunc_fib( KSContext& context )
02127 {
02128   QValueList<KSValue::Ptr>& args = context.value()->listValue();
02129   if ( !KSUtil::checkArgumentsCount( context, 1, "FIB", true ) )
02130     return false;
02131 
02132   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
02133     return false;
02134 
02135 /*
02136 Lucas' formula for the nth Fibonacci number F(n) is given by
02137 
02138          ((1+sqrt(5))/2)^n - ((1-sqrt(5))/2)^n
02139   F(n) = ------------------------------------- .
02140                          sqrt(5)
02141 
02142 */
02143   double n = args[0]->doubleValue();
02144 
02145   double s = sqrt(5.0);
02146   double result = ( pow((1+s)/2,n) - pow((1-s)/2,n) ) / s;
02147 
02148   context.setValue( new KSValue( result ) );
02149   return true;
02150 }
02151 
02152 // Function: MULTIPLEOPERATIONS
02153 bool kspreadfunc_multipleOP( KSContext& context )
02154 {
02155   if (gCell)
02156   {
02157     context.setValue( new KSValue( ((KSpreadInterpreter *) context.interpreter() )->cell()->value().asFloat() ) );
02158     return true;
02159   }
02160 
02161   gCell = ((KSpreadInterpreter *) context.interpreter() )->cell();
02162 
02163   QValueList<KSValue::Ptr>& args = context.value()->listValue();
02164   QValueList<KSValue::Ptr>& extra = context.extraData()->listValue();
02165 
02166   if ( !KSUtil::checkArgumentsCount( context, 5, "MULTIPLEOPERATIONS", true ) )
02167   {
02168     gCell = 0;
02169     return false;
02170   }
02171 
02172   // 0: cell must contain formula with double/int result
02173   // 0, 1, 2, 3, 4: must contain integer/double
02174   for (int i = 0; i < 5; ++i)
02175   {
02176     if ( !KSUtil::checkType( context, args[i], KSValue::DoubleType, true ) )
02177     {
02178       gCell = 0;
02179       return false;
02180     }
02181   }
02182 
02183   //  ((KSpreadInterpreter *) context.interpreter() )->document()->emitBeginOperation();
02184 
02185   double oldCol = args[1]->doubleValue();
02186   double oldRow = args[3]->doubleValue();
02187   kdDebug() << "Old values: Col: " << oldCol << ", Row: " << oldRow << endl;
02188 
02189   KSpreadCell * cell;
02190   KSpreadSheet * sheet = ((KSpreadInterpreter *) context.interpreter() )->sheet();
02191 
02192   KSpreadPoint point( extra[1]->stringValue() );
02193   KSpreadPoint point2( extra[3]->stringValue() );
02194   KSpreadPoint point3( extra[0]->stringValue() );
02195 
02196   if ( ( args[1]->doubleValue() != args[2]->doubleValue() )
02197        || ( args[3]->doubleValue() != args[4]->doubleValue() ) )
02198   {
02199     cell = sheet->cellAt( point.pos.x(), point.pos.y() );
02200     cell->setValue( args[2]->doubleValue() );
02201     kdDebug() << "Setting value " << args[2]->doubleValue() << " on cell " << point.pos.x()
02202               << ", " << point.pos.y() << endl;
02203 
02204     cell = sheet->cellAt( point2.pos.x(), point.pos.y() );
02205     cell->setValue( args[4]->doubleValue() );
02206     kdDebug() << "Setting value " << args[4]->doubleValue() << " on cell " << point2.pos.x()
02207               << ", " << point2.pos.y() << endl;
02208   }
02209 
02210   KSpreadCell * cell1 = sheet->cellAt( point3.pos.x(), point3.pos.y() );
02211   cell1->calc( false );
02212 
02213   double d = cell1->value().asFloat();
02214   kdDebug() << "Cell: " << point3.pos.x() << "; " << point3.pos.y() << " with value "
02215             << d << endl;
02216 
02217   kdDebug() << "Resetting old values" << endl;
02218 
02219   cell = sheet->cellAt( point.pos.x(), point.pos.y() );
02220   cell->setValue( oldCol );
02221 
02222   cell = sheet->cellAt( point2.pos.x(), point2.pos.y() );
02223   cell->setValue( oldRow );
02224 
02225   cell1->calc( false );
02226 
02227   // ((KSpreadInterpreter *) context.interpreter() )->document()->emitEndOperation();
02228 
02229   context.setValue( new KSValue( (double) d ) );
02230 
02231   gCell = 0;
02232   return true;
02233 }
02234 
02235 // Function: SUBTOTAL:
02236 bool kspreadfunc_subtotal( KSContext & context )
02237 {
02238   QValueList<KSValue::Ptr>& args = context.value()->listValue();
02239   QValueList<KSValue::Ptr>& extra = context.extraData()->listValue();
02240 
02241   if ( !KSUtil::checkArgumentsCount( context, 2, "SUBTOTAL", true ) )
02242     return false;
02243 
02244   if ( !KSUtil::checkType( context, args[0], KSValue::IntType, true ) )
02245     return false;
02246 
02247   // create a new list
02248   QValueList<KSValue::Ptr> * list = new QValueList<KSValue::Ptr>;
02249   int function = args[0]->intValue();
02250 
02251   KSValue * c = 0;
02252   KSpreadCell  * cell = 0;
02253   KSpreadSheet * sheet = ((KSpreadInterpreter *) context.interpreter() )->sheet();
02254   KSpreadMap * map = ((KSpreadInterpreter *) context.interpreter() )->document()->map();
02255 
02256   kdDebug() << "Range: " << extra[1]->stringValue() << endl;
02257 
02258   KSpreadRange range ( extra[1]->stringValue(), map, sheet );
02259   if ( !range.isValid() )
02260   {
02261     KSpreadPoint point( extra[1]->stringValue(), map, sheet );
02262 
02263     if ( !point.isValid() )
02264       return false;
02265 
02266     range.range = QRect( point.pos.x(), point.pos.y(),
02267                          point.pos.x(), point.pos.y() );
02268 
02269   }
02270 
02271   KSValue * l = new KSValue( KSValue::ListType );
02272   int count = 0;
02273   int countA = 0;
02274   double sum = 0.0;
02275   double max = 0.0;
02276 
02277   if ( function == 6 ) // product
02278     sum = 1.0;
02279 
02280   int x = range.range.left();
02281   int y = range.range.top();
02282   int bottom = range.range.bottom();
02283 
02284   for ( ; y <= bottom; ++y )
02285   {
02286     cell = sheet->cellAt( x, y );
02287     if ( cell->isDefault() || cell->text().find( "SUBTOTAL", 0, false ) != -1 )
02288       continue;
02289 
02290     ++count;
02291     if ( cell->value().isNumber() )
02292     {
02293       ++countA;
02294       if ( function == 1 || function == 9 || function == 7 || function == 8
02295            || function == 10 || function == 11 )
02296         sum += cell->value().asFloat();
02297       else if ( function == 4 )
02298       {
02299         if ( countA == 1 )
02300           max = cell->value().asFloat();
02301         else
02302         if ( cell->value().asFloat() > max )
02303           max = cell->value().asFloat();
02304       }
02305       else if ( function == 5 )
02306       {
02307         if ( countA == 1 )
02308           max = cell->value().asFloat();
02309         else
02310         if ( cell->value().asFloat() < max )
02311           max = cell->value().asFloat();
02312       }
02313       else if ( function == 6 )
02314         sum *= cell->value().asFloat();
02315     }
02316 
02317 
02318     c = new KSValue( cell->value().asFloat() );
02319     l->listValue().append( c );
02320   }
02321   list->append ( l );
02322 
02323 
02324   double result  = 0.0;
02325   double average = sum / countA;
02326 
02327   switch( function )
02328   {
02329    case 1: // Average
02330     context.setValue( new KSValue( average ) );
02331     break;
02332    case 2: // Count
02333     context.setValue( new KSValue( count ) );
02334     break;
02335    case 3: // CountA (count without blanks)
02336     context.setValue( new KSValue( countA ) );
02337     break;
02338    case 4: // MAX
02339     context.setValue( new KSValue( max ) );
02340     break;
02341    case 5: // Min
02342     context.setValue( new KSValue( max ) );
02343     break;
02344    case 6: // Product
02345     if ( countA == 0 )
02346       sum = 0.0;       // Excel compatibility :-(
02347     context.setValue( new KSValue( sum ) );
02348     break;
02349    case 7: // StDev
02350     kspreadfunc_stddev_helper( context, *list, result, average, false );
02351     context.setValue( new KSValue( sqrt( result / ((double) (countA - 1) ) ) ) );
02352     break;
02353    case 8: // StDevP
02354     kspreadfunc_stddev_helper( context, *list, result, average, false );
02355     context.setValue( new KSValue( sqrt( result / countA ) ) );
02356     break;
02357    case 9: // Sum
02358     context.setValue( new KSValue( sum ) );
02359     break;
02360    case 10: // Var
02361     kspreadfunc_variance_helper( context, *list, result, average, false );
02362     context.setValue( new KSValue( (double)(result / (countA - 1)) ) );
02363     break;
02364    case 11: // VarP
02365     kspreadfunc_variance_helper( context, *list, result, average, false );
02366     context.setValue( new KSValue( (double)(result / countA) ) );
02367     break;
02368    default:
02369     return false;
02370   }
02371 
02372   return true;
02373 }
02374 
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:11 2006 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003