kspread Library API Documentation

kspread_functions_engineering.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 engineering functions
00022 
00023 #include <stdlib.h>
00024 #include <math.h>
00025 #include <float.h>
00026 
00027 #include <qmap.h>
00028 
00029 #include <kdebug.h>
00030 #include <klocale.h>
00031 
00032 #include <koscript_parser.h>
00033 #include <koscript_util.h>
00034 #include <koscript_func.h>
00035 #include <koscript_synext.h>
00036 
00037 #include "kspread_functions.h"
00038 #include "kspread_util.h"
00039 
00040 
00041 // prototypes (sort alphabetically)
00042 bool kspreadfunc_base( KSContext& context );
00043 bool kspreadfunc_besseli( KSContext& context );
00044 bool kspreadfunc_besselj( KSContext& context );
00045 bool kspreadfunc_besselk( KSContext& context );
00046 bool kspreadfunc_bessely( KSContext& context );
00047 bool kspreadfunc_bin2dec( KSContext& context );
00048 bool kspreadfunc_bin2oct( KSContext& context );
00049 bool kspreadfunc_bin2hex( KSContext& context );
00050 bool kspreadfunc_complex( KSContext& context );
00051 bool kspreadfunc_complex_imag( KSContext& context );
00052 bool kspreadfunc_complex_real( KSContext& context );
00053 bool kspreadfunc_convert( KSContext& context );
00054 bool kspreadfunc_dec2hex( KSContext& context );
00055 bool kspreadfunc_dec2oct( KSContext& context );
00056 bool kspreadfunc_dec2bin( KSContext& context );
00057 bool kspreadfunc_delta( KSContext& context );
00058 bool kspreadfunc_erf( KSContext& context );
00059 bool kspreadfunc_erfc( KSContext& context );
00060 bool kspreadfunc_gestep( KSContext& context );
00061 bool kspreadfunc_hex2dec( KSContext& context );
00062 bool kspreadfunc_hex2bin( KSContext& context );
00063 bool kspreadfunc_hex2oct( KSContext& context );
00064 bool kspreadfunc_imabs( KSContext& context );
00065 bool kspreadfunc_imargument( KSContext& context );
00066 bool kspreadfunc_imconjugate( KSContext& context );
00067 bool kspreadfunc_imcos( KSContext& context );
00068 bool kspreadfunc_imdiv( KSContext& context );
00069 bool kspreadfunc_imexp( KSContext& context );
00070 bool kspreadfunc_imln( KSContext& context );
00071 bool kspreadfunc_impower( KSContext& context );
00072 bool kspreadfunc_improduct( KSContext& context );
00073 bool kspreadfunc_imsin( KSContext& context );
00074 bool kspreadfunc_imsqrt( KSContext& context );
00075 bool kspreadfunc_imsub( KSContext& context );
00076 bool kspreadfunc_imsum( KSContext& context );
00077 bool kspreadfunc_oct2dec( KSContext& context );
00078 bool kspreadfunc_oct2bin( KSContext& context );
00079 bool kspreadfunc_oct2hex( KSContext& context );
00080 
00081 // registers all engineering functions
00082 void KSpreadRegisterEngineeringFunctions()
00083 {
00084   KSpreadFunctionRepository* repo = KSpreadFunctionRepository::self();
00085 
00086   repo->registerFunction( "BASE",        kspreadfunc_base );    // KSpread-specific, like in Quattro-Pro
00087   repo->registerFunction( "BESSELI",     kspreadfunc_besseli );
00088   repo->registerFunction( "BESSELJ",     kspreadfunc_besselj );
00089   repo->registerFunction( "BESSELK",     kspreadfunc_besselk );
00090   repo->registerFunction( "BESSELY",     kspreadfunc_bessely );
00091   repo->registerFunction( "BIN2DEC",     kspreadfunc_bin2dec );
00092   repo->registerFunction( "BIN2OCT",     kspreadfunc_bin2oct );
00093   repo->registerFunction( "BIN2HEX",     kspreadfunc_bin2hex );
00094   repo->registerFunction( "COMPLEX",     kspreadfunc_complex );
00095   repo->registerFunction( "CONVERT",     kspreadfunc_convert );
00096   repo->registerFunction( "DEC2HEX",     kspreadfunc_dec2hex );
00097   repo->registerFunction( "DEC2BIN",     kspreadfunc_dec2bin );
00098   repo->registerFunction( "DEC2OCT",     kspreadfunc_dec2oct );
00099   repo->registerFunction( "DELTA",       kspreadfunc_delta );
00100   repo->registerFunction( "ERF",         kspreadfunc_erf );
00101   repo->registerFunction( "ERFC",        kspreadfunc_erfc );
00102   repo->registerFunction( "GESTEP",      kspreadfunc_gestep );
00103   repo->registerFunction( "HEX2BIN",     kspreadfunc_hex2bin );
00104   repo->registerFunction( "HEX2DEC",     kspreadfunc_hex2dec );
00105   repo->registerFunction( "HEX2OCT",     kspreadfunc_hex2oct );
00106   repo->registerFunction( "IMABS",       kspreadfunc_imabs );
00107   repo->registerFunction( "IMAGINARY",   kspreadfunc_complex_imag );
00108   repo->registerFunction( "IMARGUMENT",  kspreadfunc_imargument );
00109   repo->registerFunction( "IMCONJUGATE", kspreadfunc_imconjugate );
00110   repo->registerFunction( "IMCOS",       kspreadfunc_imcos );
00111   repo->registerFunction( "IMDIV",       kspreadfunc_imdiv );
00112   repo->registerFunction( "IMEXP",       kspreadfunc_imexp );
00113   repo->registerFunction( "IMLN",        kspreadfunc_imln );
00114   repo->registerFunction( "IMPOWER",     kspreadfunc_impower );
00115   repo->registerFunction( "IMPRODUCT",   kspreadfunc_improduct );
00116   repo->registerFunction( "IMREAL",      kspreadfunc_complex_real );
00117   repo->registerFunction( "IMSIN",       kspreadfunc_imsin );
00118   repo->registerFunction( "IMSQRT",      kspreadfunc_imsqrt );
00119   repo->registerFunction( "IMSUB",       kspreadfunc_imsub );
00120   repo->registerFunction( "IMSUM",       kspreadfunc_imsum );
00121   repo->registerFunction( "OCT2BIN",     kspreadfunc_oct2bin );
00122   repo->registerFunction( "OCT2DEC",     kspreadfunc_oct2dec );
00123   repo->registerFunction( "OCT2HEX",     kspreadfunc_oct2hex );
00124 }
00125 
00126 // Function: BASE
00127 bool kspreadfunc_base( KSContext& context )
00128 {
00129   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00130 
00131   int base = 10;
00132   int prec = 0;
00133 
00134   if ( KSUtil::checkArgumentsCount( context, 3, "BASE", false ) )
00135   {
00136     if ( !KSUtil::checkType( context, args[2], KSValue::IntType, true ) ) return false;
00137     if ( !KSUtil::checkType( context, args[1], KSValue::IntType, true ) ) return false;
00138     base = args[1]->intValue();
00139     prec = args[2]->intValue();
00140   }
00141   else
00142   if ( KSUtil::checkArgumentsCount( context, 2, "BASE", false ) )
00143   {
00144     if ( !KSUtil::checkType( context, args[1], KSValue::IntType, true ) ) return false;
00145     base = args[1]->intValue();
00146   }
00147   else
00148   if ( !KSUtil::checkArgumentsCount( context, 1, "BASE", true ) )
00149     return false;
00150 
00151 
00152   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) ) return false;
00153 
00154   if( ( base < 2 ) || ( base > 36 ) ) return false;
00155   if( prec < 0 ) prec = 2;
00156 
00157   double value = args[0]->doubleValue();
00158   QString result = QString::number( (int)value, base );
00159 
00160   if( prec > 0 )
00161   {
00162     result += "."; value = value - (int)value;
00163 
00164     int ix;
00165     for( int i = 0; i < prec; i++ )
00166     {
00167       ix = (int) value * base;
00168 
00169 kdDebug() << "value " << value << "  ix " << ix << endl;
00170 
00171       result += "0123456789abcdefghijklmnopqrstuvwxyz"[ix];
00172       value = base * (value - (double)ix/base);
00173     }
00174   }
00175 
00176   context.setValue( new KSValue( result.upper() ) );
00177 
00178   return true;
00179 }
00180 
00181 /*
00182  *
00183  * The code for calculating Bessel functions is taken
00184  * from CCMATH, a mathematics library source.code.
00185  *
00186  * Original copyright follows:
00187  *
00188  *  Copyright (C)  2000   Daniel A. Atkinson    All rights reserved.
00189  *  This code may be redistributed under the terms of the GNU library
00190  *  public license (LGPL).
00191  */
00192 
00193 static double ccmath_gaml(double x)
00194 { double g,h;
00195   for(g=1.; x<30. ;g*=x,x+=1.); h=x*x;
00196   g=(x-.5)*log(x)-x+.918938533204672-log(g);
00197   g+=(1.-(1./6.-(1./3.-1./(4.*h))/(7.*h))/(5.*h))/(12.*x);
00198   return g;
00199 }
00200 
00201 static double ccmath_psi(int m)
00202 { double s= -.577215664901533; int k;
00203   for(k=1; k<m ;++k) s+=1./k;
00204   return s;
00205 }
00206 
00207 static double ccmath_ibes(double v,double x)
00208 { double y,s,t,tp; int p,m;
00209   y=x-9.; if(y>0.) y*=y; tp=v*v*.2+25.;
00210   if(y<tp){ x/=2.; m=x;
00211     if(x>0.) s=t=exp(v*log(x)-ccmath_gaml(v+1.));
00212     else{ if(v>0.) return 0.; else if(v==0.) return 1.;}
00213     for(p=1,x*=x;;++p){ t*=x/(p*(v+=1.)); s+=t;
00214       if(p>m && t<1.e-13*s) break;
00215      }
00216    }
00217   else{ double u,a0=1.57079632679490;
00218     s=t=1./sqrt(x*a0); x*=2.; u=0.;
00219     for(p=1,y=.5; (tp=fabs(t))>1.e-14 ;++p,y+=1.){
00220       t*=(v+y)*(v-y)/(p*x); if(y>v && fabs(t)>=tp) break;
00221       if(!(p&1)) s+=t; else u-=t;
00222      }
00223     x/=2.; s=cosh(x)*s+sinh(x)*u;
00224    }
00225   return s;
00226 }
00227 
00228 static double ccmath_kbes(double v,double x)
00229 { double y,s,t,tp,f,a0=1.57079632679490;
00230   int p,k,m;
00231   if(x==0.) return HUGE_VAL;
00232   y=x-10.5; if(y>0.) y*=y; tp=25.+.185*v*v;
00233   if(y<tp && modf(v+.5,&t)!=0.){ y=1.5+.5*v;
00234     if(x<y){ x/=2.; m=x; tp=t=exp(v*log(x)-ccmath_gaml(v+1.));
00235       if(modf(v,&y)==0.){ k=y; tp*=v;
00236         f=2.*log(x)-ccmath_psi(1)-ccmath_psi(k+1);
00237         t/=2.; if(!(k&1)) t= -t; s=f*t;
00238         for(p=1,x*=x;;++p){ f-=1./p+1./(v+=1.);
00239           t*=x/(p*v); s+=(y=t*f);
00240           if(p>m && fabs(y)<1.e-14) break; }
00241         if(k>0){ x= -x; s+=(t=1./(tp*2.));
00242           for(p=1,--k; k>0 ;++p,--k) s+=(t*=x/(p*k)); }
00243        }
00244       else{ f=1./(t*v*2.); t*=a0/sin(2.*a0*v); s=f-t;
00245         for(p=1,x*=x,tp=v;;++p){
00246           t*=x/(p*(v+=1.)); f*= -x/(p*(tp-=1.));
00247           s+=(y=f-t); if(p>m && fabs(y)<1.e-14) break; }
00248        }
00249      }
00250     else{ double tq,h,w,z,r;
00251       t=12./pow(x,.333); k=t*t; y=2.*(x+k);
00252       m=v; v-=m; tp=v*v-.25; v+=1.; tq=v*v-.25;
00253       for(s=h=1.,r=f=z=w=0.; k>0 ;--k,y-=2.){
00254         t=(y*h-(k+1)*z)/(k-1-tp/k); z=h; f+=(h=t);
00255         t=(y*s-(k+1)*w)/(k-1-tq/k); w=s; r+=(s=t);  }
00256       t=sqrt(a0/x)*exp(-x); s*=t/r; h*=t/f; x/=2.; if(m==0) s=h;
00257       for(k=1; k<m ;++k){ t=v*s/x+h; h=s; s=t; v+=1.;}
00258      }
00259    }
00260   else{ s=t=sqrt(a0/x); x*=2.;
00261     for(p=1,y=.5; (tp=fabs(t))>1.e-14 ;++p,y+=1.){
00262       t*=(v+y)*(v-y)/(p*x); if(y>v && fabs(t)>=tp) break; s+=t; }
00263     s*=exp(-x/2.);
00264    }
00265   return s;
00266 }
00267 
00268 static double ccmath_jbes(double v,double x)
00269 { double y,s,t,tp; int p,m;
00270   y=x-8.5; if(y>0.) y*=y; tp=v*v/4.+13.69;
00271   if(y<tp){ x/=2.; m=x;
00272     if(x>0.) s=t=exp(v*log(x)-ccmath_gaml(v+1.));
00273     else{ if(v>0.) return 0.; else if(v==0.) return 1.;}
00274     for(p=1,x*= -x;;++p){ t*=x/(p*(v+=1.)); s+=t;
00275       if(p>m && fabs(t)<1.e-13) break;
00276      }
00277    }
00278   else{ double u,a0=1.57079632679490;
00279     s=t=1./sqrt(x*a0); x*=2.; u=0.;
00280     for(p=1,y=.5; (tp=fabs(t))>1.e-14 ;++p,y+=1.){
00281       t*=(v+y)*(v-y)/(p*x); if(y>v && fabs(t)>=tp) break;
00282       if(!(p&1)){ t= -t; s+=t;} else u-=t;
00283      }
00284     y=x/2.-(v+.5)*a0; s=cos(y)*s+sin(y)*u;
00285    }
00286   return s;
00287 }
00288 
00289 static double ccmath_nbes(double v,double x)
00290 { double y,s,t,tp,u,f,a0=3.14159265358979;
00291   int p,k,m;
00292   y=x-8.5; if(y>0.) y*=y; tp=v*v/4.+13.69;
00293   if(y<tp){ if(x==0.) return HUGE_VAL;
00294     x/=2.; m=x; u=t=exp(v*log(x)-ccmath_gaml(v+1.));
00295     if(modf(v,&y)==0.){ k=y; u*=v;
00296       f=2.*log(x)-ccmath_psi(1)-ccmath_psi(k+1);
00297       t/=a0; x*= -x; s=f*t;
00298       for(p=1;;++p){ f-=1./p+1./(v+=1.);
00299         t*=x/(p*v); s+=(y=t*f); if(p>m && fabs(y)<1.e-13) break; }
00300       if(k>0){ x= -x; s-=(t=1./(u*a0));
00301         for(p=1,--k; k>0 ;++p,--k) s-=(t*=x/(p*k)); }
00302      }
00303     else{ f=1./(t*v*a0); t/=tan(a0*v); s=t-f;
00304       for(p=1,x*=x,u=v;;++p){
00305         t*= -x/(p*(v+=1.)); f*=x/(p*(u-=1.));
00306         s+=(y=t-f); if(p>m && fabs(y)<1.e-13) break; }
00307      }
00308    }
00309   else{ x*=2.; s=t=2./sqrt(x*a0); u=0.;
00310     for(p=1,y=.5; (tp=fabs(t))>1.e-14 ;++p,y+=1.){
00311       t*=(v+y)*(v-y)/(p*x); if(y>v && fabs(t)>tp) break;
00312       if(!(p&1)){ t= -t; s+=t;} else u+=t;
00313      }
00314     y=(x-(v+.5)*a0)/2.; s=sin(y)*s+cos(y)*u;
00315    }
00316   return s;
00317 }
00318 
00319 
00320 /* ---------- end of CCMATH code ---------- */
00321 
00322 // Function: BESSELI
00323 bool kspreadfunc_besseli( KSContext& context )
00324 {
00325   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00326 
00327   if ( !KSUtil::checkArgumentsCount( context,2, "BESSELI",true ) )
00328     return false;
00329 
00330   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
00331     return false;
00332 
00333   if ( !KSUtil::checkType( context, args[1], KSValue::DoubleType, true ) )
00334     return false;
00335 
00336   double x = args[0]->doubleValue();
00337   double y = args[1]->doubleValue();
00338 
00339   context.setValue( new KSValue( ccmath_ibes( y, x ) ) );
00340 
00341   return true;
00342 }
00343 
00344 // Function: BESSELJ
00345 bool kspreadfunc_besselj( KSContext& context )
00346 {
00347   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00348 
00349   if ( !KSUtil::checkArgumentsCount( context,2, "BESSELJ",true ) )
00350     return false;
00351 
00352   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
00353     return false;
00354 
00355   if ( !KSUtil::checkType( context, args[1], KSValue::DoubleType, true ) )
00356     return false;
00357 
00358   double x = args[0]->doubleValue();
00359   double y = args[1]->doubleValue();
00360 
00361   context.setValue( new KSValue( ccmath_jbes( y, x ) ) );
00362 
00363   return true;
00364 }
00365 
00366 // Function: BESSELK
00367 bool kspreadfunc_besselk( KSContext& context )
00368 {
00369   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00370 
00371   if ( !KSUtil::checkArgumentsCount( context,2, "BESSELK",true ) )
00372     return false;
00373 
00374   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
00375     return false;
00376 
00377   if ( !KSUtil::checkType( context, args[1], KSValue::DoubleType, true ) )
00378     return false;
00379 
00380   double x = args[0]->doubleValue();
00381   double y = args[1]->doubleValue();
00382 
00383   context.setValue( new KSValue( ccmath_kbes( y, x ) ) );
00384 
00385   return true;
00386 }
00387 
00388 // Function: BESSELY
00389 bool kspreadfunc_bessely( KSContext& context )
00390 {
00391   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00392 
00393   if ( !KSUtil::checkArgumentsCount( context,2, "BESSELY",true ) )
00394     return false;
00395 
00396   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
00397     return false;
00398 
00399   if ( !KSUtil::checkType( context, args[1], KSValue::DoubleType, true ) )
00400     return false;
00401 
00402   double x = args[0]->doubleValue();
00403   double y = args[1]->doubleValue();
00404 
00405   context.setValue( new KSValue( ccmath_nbes( y, x ) ) );
00406 
00407   return true;
00408 }
00409 
00410 // Function: DEC2HEX
00411 bool kspreadfunc_dec2hex( KSContext& context )
00412 {
00413   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00414 
00415   if ( !KSUtil::checkArgumentsCount( context, 1, "DECHEX", true ) ||!KSUtil::checkArgumentsCount( context, 1, "DEC2HEX", true ))
00416     return false;
00417 
00418   if ( !KSUtil::checkType( context, args[0], KSValue::IntType, true ) )
00419     return false;
00420 
00421   QString tmp;
00422   tmp=tmp.setNum( args[0]->intValue(),16);
00423   context.setValue( new KSValue( tmp ));
00424 
00425   return true;
00426 }
00427 
00428 // Function: DEC2OCT
00429 bool kspreadfunc_dec2oct( KSContext& context )
00430 {
00431   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00432 
00433   if ( !KSUtil::checkArgumentsCount( context, 1, "DEC2OCT", true )  || !KSUtil::checkArgumentsCount( context, 1, "DECOCT", true ))
00434     return false;
00435 
00436   if ( !KSUtil::checkType( context, args[0], KSValue::IntType, true ) )
00437     return false;
00438 
00439   QString tmp;
00440   tmp=tmp.setNum( args[0]->intValue(),8);
00441   context.setValue( new KSValue( tmp ));
00442 
00443   return true;
00444 }
00445 
00446 // Function: DEC2BIN
00447 bool kspreadfunc_dec2bin( KSContext& context )
00448 {
00449   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00450 
00451   if ( !KSUtil::checkArgumentsCount( context, 1, "DEC2BIN", true )  || !KSUtil::checkArgumentsCount( context, 1, "DECBIN", true ))
00452     return false;
00453 
00454   if ( !KSUtil::checkType( context, args[0], KSValue::IntType, true ) )
00455     return false;
00456 
00457   QString tmp;
00458   tmp=tmp.setNum( args[0]->intValue(),2);
00459   context.setValue( new KSValue( tmp ));
00460 
00461   return true;
00462 }
00463 
00464 // Function: BIN2DEC
00465 bool kspreadfunc_bin2dec( KSContext& context )
00466 {
00467   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00468 
00469   if ( !KSUtil::checkArgumentsCount( context, 1, "BIN2DEC", true ) )
00470     return false;
00471 
00472   QString str;
00473   if ( KSUtil::checkType( context, args[0], KSValue::StringType, false ) )
00474     str = args[0]->stringValue();
00475   else if( KSUtil::checkType( context, args[0], KSValue::IntType, false ) )
00476     str = QString::number( args[0]->intValue() );
00477   else if( KSUtil::checkType( context, args[0], KSValue::DoubleType, false ) )
00478     str = QString::number( args[0]->intValue() );
00479   else
00480     return false;
00481 
00482   bool ok = true;
00483   long val = str.toLong( &ok, 2 );
00484   if( !ok )
00485     context.setValue( new KSValue( i18n("Err") ));
00486   else
00487     context.setValue( new KSValue( val ) );
00488 
00489   return true;
00490 }
00491 
00492 // Function: BIN2OCT
00493 bool kspreadfunc_bin2oct( KSContext& context )
00494 {
00495   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00496 
00497   if ( !KSUtil::checkArgumentsCount( context, 1, "BIN2OCT", true ) )
00498     return false;
00499 
00500   QString str;
00501   if ( KSUtil::checkType( context, args[0], KSValue::StringType, false ) )
00502     str = args[0]->stringValue();
00503   else if( KSUtil::checkType( context, args[0], KSValue::IntType, false ) )
00504     str = QString::number( args[0]->intValue() );
00505   else if( KSUtil::checkType( context, args[0], KSValue::DoubleType, false ) )
00506     str = QString::number( args[0]->intValue() );
00507   else
00508     return false;
00509 
00510   bool ok = true;
00511   long val = str.toLong( &ok, 2 );
00512   if( !ok )
00513     context.setValue( new KSValue( i18n("Err") ));
00514   else
00515     context.setValue( new KSValue( QString::number( val, 8 ) ) );
00516 
00517   return true;
00518 }
00519 
00520 // Function: BIN2HEX
00521 bool kspreadfunc_bin2hex( KSContext& context )
00522 {
00523   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00524 
00525   if ( !KSUtil::checkArgumentsCount( context, 1, "BIN2HEX", true ) )
00526     return false;
00527 
00528   QString str;
00529   if ( KSUtil::checkType( context, args[0], KSValue::StringType, false ) )
00530     str = args[0]->stringValue();
00531   else if( KSUtil::checkType( context, args[0], KSValue::IntType, false ) )
00532     str = QString::number( args[0]->intValue() );
00533   else if( KSUtil::checkType( context, args[0], KSValue::DoubleType, false ) )
00534     str = QString::number( args[0]->intValue() );
00535   else
00536     return false;
00537 
00538   bool ok = true;
00539   long val = str.toLong( &ok, 2 );
00540   if( !ok )
00541     context.setValue( new KSValue( i18n("Err") ));
00542   else
00543     context.setValue( new KSValue( QString::number( val, 16 ).upper() ) );
00544 
00545   return true;
00546 }
00547 
00548 // Function: OCT2DEC
00549 bool kspreadfunc_oct2dec( KSContext& context )
00550 {
00551   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00552 
00553   if ( !KSUtil::checkArgumentsCount( context, 1, "OCT2DEC", true ) )
00554     return false;
00555 
00556   QString str;
00557   if ( KSUtil::checkType( context, args[0], KSValue::StringType, false ) )
00558     str = args[0]->stringValue();
00559   else if( KSUtil::checkType( context, args[0], KSValue::IntType, false ) )
00560     str = QString::number( args[0]->intValue() );
00561   else if( KSUtil::checkType( context, args[0], KSValue::DoubleType, false ) )
00562     str = QString::number( args[0]->intValue() );
00563   else
00564     return false;
00565 
00566   bool ok = true;
00567   long val = str.toLong( &ok, 8 );
00568   if( !ok )
00569     context.setValue( new KSValue( i18n("Err") ));
00570   else
00571     context.setValue( new KSValue( val ) );
00572 
00573   return true;
00574 }
00575 
00576 // Function: OCT2BIN
00577 bool kspreadfunc_oct2bin( KSContext& context )
00578 {
00579   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00580 
00581   if ( !KSUtil::checkArgumentsCount( context, 1, "OCT2BIN", true ) )
00582     return false;
00583 
00584   QString str;
00585   if ( KSUtil::checkType( context, args[0], KSValue::StringType, false ) )
00586     str = args[0]->stringValue();
00587   else if( KSUtil::checkType( context, args[0], KSValue::IntType, false ) )
00588     str = QString::number( args[0]->intValue() );
00589   else if( KSUtil::checkType( context, args[0], KSValue::DoubleType, false ) )
00590     str = QString::number( args[0]->intValue() );
00591   else
00592     return false;
00593 
00594   bool ok = true;
00595   long val = str.toLong( &ok, 8 );
00596   if( !ok )
00597     context.setValue( new KSValue( i18n("Err") ));
00598   else
00599     context.setValue( new KSValue( QString::number( val, 2 ) ) );
00600 
00601   return true;
00602 }
00603 
00604 // Function: OCT2HEX
00605 bool kspreadfunc_oct2hex( KSContext& context )
00606 {
00607   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00608 
00609   if ( !KSUtil::checkArgumentsCount( context, 1, "OCT2HEX", true ) )
00610     return false;
00611 
00612   QString str;
00613   if ( KSUtil::checkType( context, args[0], KSValue::StringType, false ) )
00614     str = args[0]->stringValue();
00615   else if( KSUtil::checkType( context, args[0], KSValue::IntType, false ) )
00616     str = QString::number( args[0]->intValue() );
00617   else if( KSUtil::checkType( context, args[0], KSValue::DoubleType, false ) )
00618     str = QString::number( args[0]->intValue() );
00619   else
00620     return false;
00621 
00622   bool ok = true;
00623   long val = str.toLong( &ok, 8 );
00624   if( !ok )
00625     context.setValue( new KSValue( i18n("Err") ));
00626   else
00627     context.setValue( new KSValue( QString::number( val, 16 ).upper() ) );
00628 
00629   return true;
00630 }
00631 
00632 // Function: HEX2DEC
00633 bool kspreadfunc_hex2dec( KSContext& context )
00634 {
00635   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00636 
00637   if ( !KSUtil::checkArgumentsCount( context, 1, "HEX2DEC", true ) )
00638     return false;
00639 
00640   if ( !KSUtil::checkType( context, args[0], KSValue::StringType, true ) )
00641     return false;
00642 
00643   QString tmp=args[0]->stringValue();
00644   bool ok;
00645   long val=tmp.toLong(&ok,16);
00646   if(!ok)
00647         context.setValue( new KSValue( i18n("Err") ));
00648   else
00649         context.setValue( new KSValue(val));
00650 
00651   return true;
00652 }
00653 
00654 // Function: HEX2BIN
00655 bool kspreadfunc_hex2bin( KSContext& context )
00656 {
00657   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00658 
00659   if ( !KSUtil::checkArgumentsCount( context, 1, "HEX2BIN", true ) )
00660     return false;
00661 
00662   if ( !KSUtil::checkType( context, args[0], KSValue::StringType, true ) )
00663     return false;
00664 
00665   QString tmp=args[0]->stringValue();
00666   bool ok;
00667   long val=tmp.toLong(&ok,16);
00668   if(!ok)
00669         context.setValue( new KSValue( i18n("Err") ));
00670   else
00671         {
00672         tmp=tmp.setNum(val,2);
00673         context.setValue( new KSValue(tmp));
00674         }
00675 
00676   return true;
00677 }
00678 
00679 // Function: HEX2OCT
00680 bool kspreadfunc_hex2oct( KSContext& context )
00681 {
00682   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00683 
00684   if ( !KSUtil::checkArgumentsCount( context, 1, "HEX2OCT", true ) )
00685     return false;
00686 
00687   if ( !KSUtil::checkType( context, args[0], KSValue::StringType, true ) )
00688     return false;
00689 
00690   QString tmp=args[0]->stringValue();
00691   bool ok;
00692   long val=tmp.toLong(&ok,16);
00693   if(!ok)
00694         context.setValue( new KSValue( i18n("Err") ));
00695   else
00696         {
00697         tmp=tmp.setNum(val,8);
00698         context.setValue( new KSValue(tmp));
00699         }
00700 
00701   return true;
00702 }
00703 
00704 
00705 // check if unit may contain prefix, for example "kPa" is "Pa" with
00706 // return prefix factor found in unit, or 1.0 for no prefix
00707 // also modify the unit, i.e stripping the prefix from it
00708 // example: "kPa" will return 1e3 and change unit into "Pa"
00709 static double kspread_convert_prefix( QMap<QString,double> map, QString& unit )
00710 {
00711   if( map.contains( unit ) )
00712     return 1.0;
00713 
00714   // initialize prefix mapping if necessary
00715   static QMap<char,double> prefixMap;
00716   if( prefixMap.isEmpty() )
00717   {
00718      prefixMap[ 'E' ] = 1e18;  //  exa
00719      prefixMap[ 'P' ] = 1e15;  //  peta
00720      prefixMap[ 'T' ] = 1e12;  // tera
00721      prefixMap[ 'G' ] = 1e9;   // giga
00722      prefixMap[ 'M' ] = 1e6;   // mega
00723      prefixMap[ 'k' ] = 1e3;   // kilo
00724      prefixMap[ 'h' ] = 1e2;   // hecto
00725      prefixMap[ 'e' ] = 1e1;   // dekao
00726      prefixMap[ 'd' ] = 1e1;   // deci
00727      prefixMap[ 'c' ] = 1e2;   // centi
00728      prefixMap[ 'm' ] = 1e3;   // milli
00729      prefixMap[ 'u' ] = 1e6;   // micro
00730      prefixMap[ 'n' ] = 1e9;   // nano
00731      prefixMap[ 'p' ] = 1e12;  // pico
00732      prefixMap[ 'f' ] = 1e15;  // femto
00733      prefixMap[ 'a' ] = 1e18;  // atto
00734   }
00735 
00736   // check for possible prefix
00737   char prefix = unit[0].latin1();
00738   if( prefixMap.contains( prefix ) )
00739   {
00740     unit.remove( 0, 1 );
00741     return prefixMap[ prefix ];
00742   }
00743 
00744   // fail miserably
00745   return 0.0;
00746 }
00747 
00748 static bool kspread_convert_mass( const QString& fromUnit,
00749   const QString& toUnit, double value, double& result )
00750 {
00751   static QMap<QString, double> massMap;
00752 
00753   // first-time initialization
00754   if( massMap.isEmpty() )
00755   {
00756     massMap[ "g" ]        = 1.0; // Gram (the reference )
00757     massMap[ "sg" ]       = 6.8522050005347800E-05; // Pieces
00758     massMap[ "lbm" ]      = 2.2046229146913400E-03; // Pound
00759     massMap[ "u" ]        = 6.0221370000000000E23; // U (atomic mass)
00760     massMap[ "ozm" ]      = 3.5273971800362700E-02; // Ounce
00761     massMap[ "stone" ]    = 1.574730e-04; // Stone
00762     massMap[ "ton" ]      = 1.102311e-06; // Ton
00763     massMap[ "grain" ]    = 1.543236E01;  // Grain
00764     massMap[ "pweight" ]  = 7.054792E-01; // Pennyweight
00765     massMap[ "hweight" ]  = 1.968413E-05; // Hundredweight
00766     massMap[ "shweight" ] = 2.204623E-05; // Shorthundredweight
00767     massMap[ "brton" ]    = 9.842065E-07; // Gross Registered Ton
00768   }
00769 
00770   QString fromU = fromUnit;
00771   QString toU = toUnit;
00772   double fromPrefix = kspread_convert_prefix( massMap, fromU );
00773   double toPrefix = kspread_convert_prefix( massMap, toU );
00774   if( fromPrefix == 0.0 ) return false;
00775   if( toPrefix == 0.0 ) return false;
00776   if( !massMap.contains( fromU ) ) return false;
00777   if( !massMap.contains( toU ) ) return false;
00778 
00779   result = value * fromPrefix * massMap[toU] / (massMap[fromU] * toPrefix);
00780 
00781   return true;
00782 }
00783 
00784 
00785 static bool kspread_convert_distance( const QString& fromUnit,
00786   const QString& toUnit, double value, double& result )
00787 {
00788   static QMap<QString, double> distanceMap;
00789 
00790   // first-time initialization
00791   if( distanceMap.isEmpty() )
00792   {
00793     distanceMap[ "m" ]         = 1.0;  // meter (the reference)
00794     distanceMap[ "in" ]        = 1.0 / 0.0254; // inch
00795     distanceMap[ "ft" ]        = 1.0 / (12.0 * 0.0254); // feet
00796     distanceMap[ "yd" ]        = 1.0 / (3.0 * 12.0 * 0.0254); // yar
00797     distanceMap[ "mi" ]        = 6.2137119223733397e-4; // mile
00798     distanceMap[ "Nmi" ]       = 5.3995680345572354e-04; // nautical mile
00799     distanceMap[ "ang" ]       = 1e10; // Angstrom
00800     distanceMap[ "parsec" ]    = 3.240779e-17; // Parsec
00801     distanceMap[ "lightyear" ] = 1.057023455773293e-16; // lightyear
00802   }
00803 
00804   QString fromU = fromUnit;
00805   QString toU = toUnit;
00806   double fromPrefix = kspread_convert_prefix( distanceMap, fromU );
00807   double toPrefix = kspread_convert_prefix( distanceMap, toU );
00808   if( fromPrefix == 0.0 ) return false;
00809   if( toPrefix == 0.0 ) return false;
00810   if( !distanceMap.contains( fromU ) ) return false;
00811   if( !distanceMap.contains( toU ) ) return false;
00812 
00813   result = value * fromPrefix * distanceMap[toU] / (distanceMap[fromU] * toPrefix);
00814 
00815   return true;
00816 }
00817 
00818 static bool kspread_convert_pressure( const QString& fromUnit,
00819   const QString& toUnit, double value, double& result )
00820 {
00821   static QMap<QString, double> pressureMap;
00822 
00823   // first-time initialization
00824   if( pressureMap.isEmpty() )
00825   {
00826     pressureMap[ "Pa" ] = 1.0;
00827     pressureMap[ "atm" ] = 0.9869233e-5;
00828     pressureMap[ "mmHg" ] = 0.00750061708;
00829     pressureMap[ "psi" ] = 1 / 6894.754;
00830     pressureMap[ "Torr" ] = 1 / 133.32237;
00831   }
00832 
00833   QString fromU = fromUnit;
00834   QString toU = toUnit;
00835   double fromPrefix = kspread_convert_prefix( pressureMap, fromU );
00836   double toPrefix = kspread_convert_prefix( pressureMap, toU );
00837   if( fromPrefix == 0.0 ) return false;
00838   if( toPrefix == 0.0 ) return false;
00839   if( !pressureMap.contains( fromU ) ) return false;
00840   if( !pressureMap.contains( toU ) ) return false;
00841 
00842   result = value * fromPrefix * pressureMap[toU] / (pressureMap[fromU] * toPrefix);
00843 
00844   return true;
00845 }
00846 
00847 static bool kspread_convert_force( const QString& fromUnit,
00848   const QString& toUnit, double value, double& result )
00849 {
00850   static QMap<QString, double> forceMap;
00851 
00852   // first-time initialization
00853   if( forceMap.isEmpty() )
00854   {
00855     forceMap[ "N" ]      = 1.0; // Newton (reference)
00856     forceMap[ "dyn" ]    = 1.0e5; // dyn
00857     forceMap[ "pond" ]   = 1.019716e2; // pond
00858   }
00859 
00860   QString fromU = fromUnit;
00861   QString toU = toUnit;
00862   double fromPrefix = kspread_convert_prefix( forceMap, fromU );
00863   double toPrefix = kspread_convert_prefix( forceMap, toU );
00864   if( fromPrefix == 0.0 ) return false;
00865   if( toPrefix == 0.0 ) return false;
00866   if( !forceMap.contains( fromU ) ) return false;
00867   if( !forceMap.contains( toU ) ) return false;
00868 
00869   result = value * fromPrefix * forceMap[toU] / (forceMap[fromU] * toPrefix);
00870 
00871   return true;
00872 }
00873 
00874 static bool kspread_convert_energy( const QString& fromUnit,
00875   const QString& toUnit, double value, double& result )
00876 {
00877   static QMap<QString, double> energyMap;
00878 
00879   // first-time initialization
00880   if( energyMap.isEmpty() )
00881   {
00882     energyMap[ "J" ]   = 1.0; // Joule (the reference)
00883     energyMap[ "e" ]   = 1.0e7; //erg
00884     energyMap[ "c" ]   = 0.239006249473467; // thermodynamical calorie
00885     energyMap[ "cal" ] = 0.238846190642017; // calorie
00886     energyMap[ "eV" ]  = 6.241457e+18; // electronvolt
00887     energyMap[ "HPh" ] = 3.72506111e-7; // horsepower-hour
00888     energyMap[ "Wh" ]  = 0.000277778; // watt-hour
00889     energyMap[ "flb" ] = 23.73042222;
00890     energyMap[ "BTU" ] = 9.47815067349015e-4; // British Thermal Unit
00891   }
00892 
00893   QString fromU = fromUnit;
00894   QString toU = toUnit;
00895   double fromPrefix = kspread_convert_prefix( energyMap, fromU );
00896   double toPrefix = kspread_convert_prefix( energyMap, toU );
00897   if( fromPrefix == 0.0 ) return false;
00898   if( toPrefix == 0.0 ) return false;
00899   if( !energyMap.contains( fromU ) ) return false;
00900   if( !energyMap.contains( toU ) ) return false;
00901 
00902   result = value * fromPrefix * energyMap[toU] / (energyMap[fromU] * toPrefix);
00903 
00904   return true;
00905 }
00906 
00907 static bool kspread_convert_power( const QString& fromUnit,
00908   const QString& toUnit, double value, double& result )
00909 {
00910   static QMap<QString, double> powerMap;
00911 
00912   // first-time initialization
00913   if( powerMap.isEmpty() )
00914   {
00915     powerMap[ "W" ]   = 1.0; // Watt (the reference)
00916     powerMap[ "HP" ]  = 1.341022e-3; // Horsepower
00917     powerMap[ "PS" ]  = 1.359622e-3; // Pferdestärke (German)
00918   }
00919 
00920   QString fromU = fromUnit;
00921   QString toU = toUnit;
00922   double fromPrefix = kspread_convert_prefix( powerMap, fromU );
00923   double toPrefix = kspread_convert_prefix( powerMap, toU );
00924   if( fromPrefix == 0.0 ) return false;
00925   if( toPrefix == 0.0 ) return false;
00926   if( !powerMap.contains( fromU ) ) return false;
00927   if( !powerMap.contains( toU ) ) return false;
00928 
00929   result = value * fromPrefix * powerMap[toU] / (powerMap[fromU] * toPrefix);
00930 
00931   return true;
00932 }
00933 
00934 static bool kspread_convert_magnetism( const QString& fromUnit,
00935   const QString& toUnit, double value, double& result )
00936 {
00937   static QMap<QString, double> magnetismMap;
00938 
00939   // first-time initialization
00940   if( magnetismMap.isEmpty() )
00941   {
00942     magnetismMap[ "T" ]   = 1.0;    // Tesla (the reference)
00943     magnetismMap[ "ga" ]   = 1.0e4; // Gauss
00944   }
00945 
00946   QString fromU = fromUnit;
00947   QString toU = toUnit;
00948   double fromPrefix = kspread_convert_prefix( magnetismMap, fromU );
00949   double toPrefix = kspread_convert_prefix( magnetismMap, toU );
00950   if( fromPrefix == 0.0 ) return false;
00951   if( toPrefix == 0.0 ) return false;
00952   if( !magnetismMap.contains( fromU ) ) return false;
00953   if( !magnetismMap.contains( toU ) ) return false;
00954 
00955   result = value * fromPrefix * magnetismMap[toU] / (magnetismMap[fromU] * toPrefix);
00956 
00957   return true;
00958 }
00959 
00960 static bool kspread_convert_temperature( const QString& fromUnit,
00961   const QString& toUnit, double value, double& result )
00962 {
00963   static QMap<QString, double> tempFactorMap;
00964   static QMap<QString, double> tempOffsetMap;
00965 
00966   // first-time initialization
00967   if( tempFactorMap.isEmpty() || tempOffsetMap.isEmpty() )
00968   {
00969     tempFactorMap[ "C" ] = 1.0; tempOffsetMap[ "C" ] = 0.0;
00970     tempFactorMap[ "F" ] = 5.0/9.0; tempOffsetMap[ "F" ] = -32.0;
00971     tempFactorMap[ "K" ] = 1.0; tempOffsetMap[ "K" ] = -273.15;
00972   }
00973 
00974   if( !tempFactorMap.contains( fromUnit ) ) return false;
00975   if( !tempOffsetMap.contains( fromUnit ) ) return false;
00976   if( !tempFactorMap.contains( toUnit ) ) return false;
00977   if( !tempOffsetMap.contains( toUnit ) ) return false;
00978 
00979   result = ( value + tempOffsetMap[ fromUnit ] )* tempFactorMap[ fromUnit ];
00980   result = ( result / tempFactorMap[ toUnit ] ) - tempOffsetMap[ toUnit ];
00981 
00982   return true;
00983 }
00984 
00985 static bool kspread_convert_volume( const QString& fromUnit,
00986   const QString& toUnit, double value, double& result )
00987 {
00988   static QMap<QString, double> volumeMap;
00989 
00990   // first-time initialization
00991   if( volumeMap.isEmpty() )
00992   {
00993     volumeMap[ "l" ]      = 1.0; // Liter (the reference)
00994     volumeMap[ "tsp" ]    = 202.84; // teaspoon
00995     volumeMap[ "tbs" ]    = 67.6133333333333; // sheetspoon
00996     volumeMap[ "oz" ]     = 33.8066666666667; // ounce liquid
00997     volumeMap[ "cup" ]    = 4.22583333333333; // cup
00998     volumeMap[ "pt" ]     = 2.11291666666667; // pint
00999     volumeMap[ "qt" ]     = 1.05645833333333; // quart
01000     volumeMap[ "gal" ]    = 0.26411458333333; // gallone
01001     volumeMap[ "m3" ]     = 1.0e-3; // cubic meter
01002     volumeMap[ "mi3" ]    = 2.3991275857892772e-13; // cubic mile
01003     volumeMap[ "Nmi3" ]   = 1.5742621468581148e-13; // cubic Nautical mile
01004     volumeMap[ "in3" ]    = 6.1023744094732284e1; // cubic inch
01005     volumeMap[ "ft3" ]    = 3.5314666721488590e-2; // cubic foot
01006     volumeMap[ "yd3" ]    = 1.3079506193143922; // cubic yard
01007     volumeMap[ "barrel" ] = 6.289811E-03; // barrel
01008   }
01009 
01010   QString fromU = fromUnit;
01011   QString toU = toUnit;
01012   double fromPrefix = kspread_convert_prefix( volumeMap, fromU );
01013   double toPrefix = kspread_convert_prefix( volumeMap, toU );
01014   if( fromPrefix == 0.0 ) return false;
01015   if( toPrefix == 0.0 ) return false;
01016   if( !volumeMap.contains( fromU ) ) return false;
01017   if( !volumeMap.contains( toU ) ) return false;
01018 
01019   result = value * fromPrefix * volumeMap[toU] / (volumeMap[fromU] * toPrefix);
01020 
01021   return true;
01022 }
01023 
01024 static bool kspread_convert_area( const QString& fromUnit,
01025   const QString& toUnit, double value, double& result )
01026 {
01027   static QMap<QString, double> areaMap;
01028 
01029   // first-time initialization
01030   if( areaMap.isEmpty() )
01031   {
01032     areaMap[ "m2" ]   = 1.0; // square meter (the reference)
01033     areaMap[ "mi2" ]  = 3.8610215854244585e-7; // square mile
01034     areaMap[ "Nmi2" ] = 2.9155334959812286e-7; // square Nautical mile
01035     areaMap[ "in2" ]  = 1.5500031000062000e3; // square inch
01036     areaMap[ "ft2" ]  = 1.0763910416709722e1; // square foot
01037     areaMap[ "yd2" ]  = 1.0936132983377078; // square yard
01038     areaMap[ "acre" ] = 4.046856e3; // acre
01039     areaMap[ "ha" ]   = 1.0e4; // hectare
01040   }
01041 
01042   QString fromU = fromUnit;
01043   QString toU = toUnit;
01044   double fromPrefix = kspread_convert_prefix( areaMap, fromU );
01045   double toPrefix = kspread_convert_prefix( areaMap, toU );
01046   if( fromPrefix == 0.0 ) return false;
01047   if( toPrefix == 0.0 ) return false;
01048   if( !areaMap.contains( fromU ) ) return false;
01049   if( !areaMap.contains( toU ) ) return false;
01050 
01051   result = value * fromPrefix * areaMap[toU] / (areaMap[fromU] * toPrefix);
01052 
01053   return true;
01054 }
01055 
01056 static bool kspread_convert_speed( const QString& fromUnit,
01057   const QString& toUnit, double value, double& result )
01058 {
01059   static QMap<QString, double> speedMap;
01060 
01061   // first-time initialization
01062   if( speedMap.isEmpty() )
01063   {
01064     speedMap[ "m/s" ] = 1.0; // meters per second (the reference)
01065     speedMap[ "m/h" ] = 3.6e3; // meters per hour
01066     speedMap[ "mph" ] = 2.2369362920544023; // miles per hour
01067     speedMap[ "kn" ]  = 1.9438444924406048; // knot
01068   }
01069 
01070   QString fromU = fromUnit;
01071   QString toU = toUnit;
01072   double fromPrefix = kspread_convert_prefix( speedMap, fromU );
01073   double toPrefix = kspread_convert_prefix( speedMap, toU );
01074   if( fromPrefix == 0.0 ) return false;
01075   if( toPrefix == 0.0 ) return false;
01076   if( !speedMap.contains( fromU ) ) return false;
01077   if( !speedMap.contains( toU ) ) return false;
01078 
01079   result = value * fromPrefix * speedMap[toU] / (speedMap[fromU] * toPrefix);
01080 
01081   return true;
01082 }
01083 
01084 
01085 // Function: CONVERT
01086 bool kspreadfunc_convert( KSContext& context )
01087 {
01088   QValueList<KSValue::Ptr>& args = context.value()->listValue();
01089 
01090   if ( !KSUtil::checkArgumentsCount( context, 3, "CONVERT", true ) )
01091     return false;
01092 
01093   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01094     return false;
01095 
01096   if ( !KSUtil::checkType( context, args[1], KSValue::StringType, true ) )
01097     return false;
01098 
01099   if ( !KSUtil::checkType( context, args[2], KSValue::StringType, true ) )
01100     return false;
01101 
01102   double value = args[0]->doubleValue();
01103   QString fromUnit = args[1]->stringValue();
01104   QString toUnit = args[2]->stringValue();
01105 
01106   double result = value;
01107 
01108   if( !kspread_convert_mass( fromUnit, toUnit, value, result ) )
01109     if( !kspread_convert_distance( fromUnit, toUnit, value, result ) )
01110       if( !kspread_convert_pressure( fromUnit, toUnit, value, result ) )
01111         if( !kspread_convert_force( fromUnit, toUnit, value, result ) )
01112           if( !kspread_convert_energy( fromUnit, toUnit, value, result ) )
01113             if( !kspread_convert_power( fromUnit, toUnit, value, result ) )
01114               if( !kspread_convert_magnetism( fromUnit, toUnit, value, result ) )
01115                 if( !kspread_convert_temperature( fromUnit, toUnit, value, result ) )
01116                   if( !kspread_convert_volume( fromUnit, toUnit, value, result ) )
01117                     if( !kspread_convert_area( fromUnit, toUnit, value, result ) )
01118                       if( !kspread_convert_speed( fromUnit, toUnit, value, result ) )
01119                         return false;
01120 
01121   context.setValue( new KSValue( result ) );
01122 
01123   return true;
01124 }
01125 
01126 
01127 
01128 static QString kspreadfunc_create_complex( double real,double imag )
01129 {
01130   QString tmp,tmp2;
01131   if(imag ==0)
01132         {
01133         return KGlobal::locale()->formatNumber( real);
01134         }
01135   if(real!=0)
01136         tmp=KGlobal::locale()->formatNumber(real);
01137   else
01138     return KGlobal::locale()->formatNumber(imag)+"i";
01139   if (imag >0)
01140         tmp=tmp+"+"+KGlobal::locale()->formatNumber(imag)+"i";
01141   else
01142         tmp=tmp+KGlobal::locale()->formatNumber(imag)+"i";
01143   return tmp;
01144 
01145 }
01146 
01147 // Function: COMPLEX
01148 bool kspreadfunc_complex( KSContext& context )
01149 {
01150   QValueList<KSValue::Ptr>& args = context.value()->listValue();
01151 
01152   if ( !KSUtil::checkArgumentsCount( context,2, "COMPLEX",true ) )
01153     return false;
01154 
01155   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01156     return false;
01157 
01158   if ( !KSUtil::checkType( context, args[1], KSValue::DoubleType, true ) )
01159     return false;
01160   if(args[1]->doubleValue() ==0)
01161         {
01162         context.setValue( new KSValue(args[0]->doubleValue()));
01163         return true;
01164         }
01165   QString tmp=kspreadfunc_create_complex(args[0]->doubleValue(),args[1]->doubleValue());
01166   bool ok;
01167   double result=KGlobal::locale()->readNumber(tmp, &ok);
01168   if(ok)
01169         {
01170         context.setValue( new KSValue(result));
01171         return true;
01172         }
01173   context.setValue( new KSValue(tmp));
01174 
01175   return true;
01176 }
01177 
01178 
01179 static double imag_complexe(QString str, bool &ok)
01180 {
01181 QString tmp=str;
01182 if(tmp.find('i')==-1)
01183         {  //not a complex
01184         ok=true;
01185         return 0;
01186         }
01187 else if( tmp.length()==1)
01188         {
01189         // i
01190         ok=true;
01191         return 1;
01192         }
01193 else  if( tmp.length()==2 )
01194         {
01195         //-i,+i,
01196         int pos1;
01197         if((pos1=tmp.find('+'))!=-1&& pos1==0)
01198                 {
01199                 ok=true;
01200                 return 1;
01201                 }
01202         else if( (pos1=tmp.find('-'))!=-1 && pos1==0 )
01203                 {
01204                 ok=true;
01205                 return -1;
01206                 }
01207         else if(tmp[0].isDigit())
01208                 { //5i
01209                 ok=true;
01210                 return KGlobal::locale()->readNumber(tmp.left(1));
01211                 }
01212         else
01213                 {
01214                 ok=false;
01215                 return 0;
01216                 }
01217         }
01218 else
01219         {//12+12i
01220         int pos1,pos2;
01221         if((pos1=tmp.find('i'))!=-1)
01222                 {
01223                 double val;
01224                 QString tmpStr;
01225 
01226                 if((pos2=tmp.findRev('+'))!=-1 && pos2!=0)
01227                         {
01228                         if((pos1-pos2)==1)
01229                                 {
01230                                  ok=true;
01231                                  return 1;
01232                                 }
01233                         else
01234                                 {
01235                                 tmpStr=tmp.mid(pos2,(pos1-pos2));
01236                                 val=KGlobal::locale()->readNumber(tmpStr, &ok);
01237                                 if(!ok)
01238                                         val=0;
01239                                 return val;
01240                                 }
01241                         }
01242                 else if( (pos2=tmp.findRev('-'))!=-1&& pos2!=0)
01243                         {
01244                         if((pos1-pos2)==1)
01245                                 {
01246                                  ok=true;
01247                                  return -1;
01248                                 }
01249                         else
01250                                 {
01251                                 tmpStr=tmp.mid(pos2,(pos1-pos2));
01252                                 val=KGlobal::locale()->readNumber(tmpStr, &ok);
01253                                 if(!ok)
01254                                         val=0;
01255                                 return val;
01256                                 }
01257                         }
01258                 else
01259                         {//15.55i
01260                         tmpStr=tmp.left(pos1);
01261                         val=KGlobal::locale()->readNumber(tmpStr, &ok);
01262                         if(!ok)
01263                                 val=0;
01264                         return val;
01265                         }
01266                 }
01267         }
01268 ok=false;
01269 return 0;
01270 }
01271 
01272 // Function: IMAGINARY
01273 bool kspreadfunc_complex_imag( KSContext& context )
01274 {
01275   QValueList<KSValue::Ptr>& args = context.value()->listValue();
01276 
01277   if ( !KSUtil::checkArgumentsCount( context,1, "IMAGINARY",true ) )
01278     return false;
01279   QString tmp;
01280   if ( !KSUtil::checkType( context, args[0], KSValue::StringType, true ) )
01281         {
01282         if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01283                 return false;
01284         tmp=KGlobal::locale()->formatNumber(args[0]->doubleValue());
01285         }
01286   else
01287         {
01288         tmp=args[0]->stringValue();
01289         }
01290   bool good;
01291   double result=imag_complexe(tmp, good);
01292   if(good)
01293         context.setValue( new KSValue(result));
01294   else
01295         context.setValue( new KSValue(i18n("Err")));
01296 
01297   return true;
01298 }
01299 
01300 
01301 static double real_complexe(QString str, bool &ok)
01302 {
01303 double val;
01304 int pos1,pos2;
01305 QString tmp=str;
01306 QString tmpStr;
01307 if((pos1=tmp.find('i'))==-1)
01308         { //12.5
01309         val=KGlobal::locale()->readNumber(tmp, &ok);
01310         if(!ok)
01311                 val=0;
01312         return val;
01313         }
01314 else
01315         { //15-xi
01316         if((pos2=tmp.findRev('-'))!=-1 && pos2!=0)
01317                 {
01318                 tmpStr=tmp.left(pos2);
01319                 val=KGlobal::locale()->readNumber(tmpStr, &ok);
01320                 if(!ok)
01321                         val=0;
01322                 return val;
01323                 } //15+xi
01324         else if((pos2=tmp.findRev('+'))!=-1)
01325                 {
01326                 tmpStr=tmp.left(pos2);
01327                 val=KGlobal::locale()->readNumber(tmpStr, &ok);
01328                 if(!ok)
01329                         val=0;
01330                 return val;
01331                 }
01332         else
01333                 {
01334                 ok=true;
01335                 return 0;
01336                 }
01337         }
01338 
01339 ok=false;
01340 return 0;
01341 }
01342 
01343 // Function: IMREAL
01344 bool kspreadfunc_complex_real( KSContext& context )
01345 {
01346   QValueList<KSValue::Ptr>& args = context.value()->listValue();
01347 
01348   if ( !KSUtil::checkArgumentsCount( context,1, "IMREAL",true ) )
01349     return false;
01350   QString tmp;
01351   if ( !KSUtil::checkType( context, args[0], KSValue::StringType, true ) )
01352         {
01353         if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01354                 return false;
01355         tmp=KGlobal::locale()->formatNumber(args[0]->doubleValue());
01356         }
01357   else
01358         tmp=args[0]->stringValue();
01359   bool good;
01360   double result=real_complexe(tmp, good);
01361   if(good)
01362         context.setValue( new KSValue(result));
01363   else
01364         context.setValue( new KSValue(i18n("Err")));
01365 
01366   return true;
01367 }
01368 
01369 
01370 static bool kspreadfunc_imsum_helper( KSContext& context, QValueList<KSValue::Ptr>& args, QString& result )
01371 {
01372   QValueList<KSValue::Ptr>::Iterator it = args.begin();
01373   QValueList<KSValue::Ptr>::Iterator end = args.end();
01374 
01375   for( ; it != end; ++it )
01376   {
01377     if ( KSUtil::checkType( context, *it, KSValue::ListType, false ) )
01378     {
01379       if ( !kspreadfunc_imsum_helper( context, (*it)->listValue(), result ) )
01380         return false;
01381     }
01382     else if ( KSUtil::checkType( context, *it, KSValue::StringType, true ) )
01383       {
01384       double imag,real,imag1,real1;
01385       bool ok;
01386       imag=imag_complexe(result, ok);
01387       real=real_complexe(result,  ok);
01388       imag1=imag_complexe((*it)->stringValue(), ok);
01389       real1=real_complexe((*it)->stringValue(), ok);
01390       result=kspreadfunc_create_complex(real+real1,imag+imag1);
01391       }
01392     else if ( KSUtil::checkType( context, *it, KSValue::DoubleType, true ) )
01393       {
01394       double imag,real,imag1,real1;
01395       bool ok;
01396       imag=imag_complexe(result, ok);
01397       real=real_complexe(result,  ok);
01398       imag1=0;
01399       real1=(*it)->doubleValue();
01400       result=kspreadfunc_create_complex(real+real1,imag+imag1);
01401       }
01402     else
01403       return false;
01404   }
01405 
01406   return true;
01407 }
01408 
01409 // Function: IMSUM
01410 bool kspreadfunc_imsum( KSContext& context )
01411 {
01412   QString result ;
01413   bool b = kspreadfunc_imsum_helper( context, context.value()->listValue(), result );
01414   bool ok;
01415   QString tmp;
01416   double val=KGlobal::locale()->readNumber(result, &ok);
01417   if(ok&&b)
01418         context.setValue( new KSValue( val ) );
01419   else if ( b )
01420     context.setValue( new KSValue( result ) );
01421 
01422   return b;
01423 }
01424 
01425 static bool kspreadfunc_imsub_helper( KSContext& context, QValueList<KSValue::Ptr>& args, QString& result )
01426 {
01427   QValueList<KSValue::Ptr>::Iterator it = args.begin();
01428   QValueList<KSValue::Ptr>::Iterator end = args.end();
01429 
01430   for( ; it != end; ++it )
01431   {
01432     if ( KSUtil::checkType( context, *it, KSValue::ListType, false ) )
01433     {
01434       if ( !kspreadfunc_imsub_helper( context, (*it)->listValue(), result ) )
01435         return false;
01436     }
01437     else if ( KSUtil::checkType( context, *it, KSValue::StringType, true ) )
01438       {
01439       double imag,real,imag1,real1;
01440       bool ok;
01441       if(!result.isEmpty())
01442         {
01443         imag=imag_complexe(result, ok);
01444         real=real_complexe(result,  ok);
01445         imag1=imag_complexe((*it)->stringValue(), ok);
01446         real1=real_complexe((*it)->stringValue(), ok);
01447         result=kspreadfunc_create_complex(real-real1,imag-imag1);
01448         }
01449       else
01450         {
01451         imag1=imag_complexe((*it)->stringValue(), ok);
01452         real1=real_complexe((*it)->stringValue(), ok);
01453         result=kspreadfunc_create_complex(real1,imag1);
01454         }
01455       }
01456     else if ( KSUtil::checkType( context, *it, KSValue::DoubleType, true ) )
01457       {
01458       double imag,real,imag1,real1;
01459       bool ok;
01460       imag=imag_complexe(result, ok);
01461       real=real_complexe(result,  ok);
01462       imag1=0;
01463       real1=(*it)->doubleValue();
01464       if(!result.isEmpty())
01465         result=kspreadfunc_create_complex(real-real1,imag-imag1);
01466       else
01467         result=kspreadfunc_create_complex(real1,imag1);
01468       }
01469     else
01470       return false;
01471   }
01472 
01473   return true;
01474 }
01475 
01476 // Function: IMSUB
01477 bool kspreadfunc_imsub( KSContext& context )
01478 {
01479   QString result ;
01480   bool b = kspreadfunc_imsub_helper( context, context.value()->listValue(), result );
01481   bool ok;
01482   QString tmp;
01483   double val=KGlobal::locale()->readNumber(result, &ok);
01484   if(ok&&b)
01485         context.setValue( new KSValue( val ) );
01486   else if ( b )
01487     context.setValue( new KSValue( result ) );
01488 
01489   return b;
01490 }
01491 
01492 
01493 static bool kspreadfunc_improduct_helper( KSContext& context, QValueList<KSValue::Ptr>& args, QString& result )
01494 {
01495   QValueList<KSValue::Ptr>::Iterator it = args.begin();
01496   QValueList<KSValue::Ptr>::Iterator end = args.end();
01497 
01498   for( ; it != end; ++it )
01499   {
01500     if ( KSUtil::checkType( context, *it, KSValue::ListType, false ) )
01501     {
01502       if ( !kspreadfunc_improduct_helper( context, (*it)->listValue(), result ) )
01503         return false;
01504     }
01505     else if ( KSUtil::checkType( context, *it, KSValue::StringType, true ) )
01506       {
01507       double imag,real,imag1,real1;
01508       bool ok;
01509       if(!result.isEmpty())
01510         {
01511         imag=imag_complexe(result, ok);
01512         real=real_complexe(result,  ok);
01513         imag1=imag_complexe((*it)->stringValue(), ok);
01514         real1=real_complexe((*it)->stringValue(), ok);
01515         result=kspreadfunc_create_complex(real*real1+(imag*imag1)*-1,real*imag1+real1*imag);
01516         }
01517       else
01518         {
01519         imag1=imag_complexe((*it)->stringValue(), ok);
01520         real1=real_complexe((*it)->stringValue(), ok);
01521         result=kspreadfunc_create_complex(real1,imag1);
01522         }
01523       }
01524     else if ( KSUtil::checkType( context, *it, KSValue::DoubleType, true ) )
01525       {
01526       double imag,real,imag1,real1;
01527       bool ok;
01528       imag=imag_complexe(result, ok);
01529       real=real_complexe(result,  ok);
01530       imag1=0;
01531       real1=(*it)->doubleValue();
01532       if(!result.isEmpty())
01533         result=kspreadfunc_create_complex(real*real1+(imag*imag1)*-1,real*imag1+real1*imag);
01534       else
01535         result=kspreadfunc_create_complex(real1,imag1);
01536       }
01537     else
01538       return false;
01539   }
01540 
01541   return true;
01542 }
01543 
01544 // Function: IMPRODUCT
01545 bool kspreadfunc_improduct( KSContext& context )
01546 {
01547   QString result ;
01548   bool b = kspreadfunc_improduct_helper( context, context.value()->listValue(), result );
01549   bool ok;
01550   QString tmp;
01551   double val=KGlobal::locale()->readNumber(result, &ok);
01552   if(ok&&b)
01553         context.setValue( new KSValue( val ) );
01554   else if ( b )
01555     context.setValue( new KSValue( result ) );
01556 
01557   return b;
01558 }
01559 
01560 // Function: IMCONJUGATE
01561 bool kspreadfunc_imconjugate( KSContext& context )
01562 {
01563   QValueList<KSValue::Ptr>& args = context.value()->listValue();
01564 
01565   if ( !KSUtil::checkArgumentsCount( context,1, "IMCONJUGATE",true ) )
01566     return false;
01567   QString tmp;
01568   if ( !KSUtil::checkType( context, args[0], KSValue::StringType, true ) )
01569         {
01570         if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01571                 return false;
01572         tmp=KGlobal::locale()->formatNumber(args[0]->doubleValue());
01573         }
01574   else
01575         {
01576         tmp=args[0]->stringValue();
01577         }
01578   bool ok;
01579   double real=real_complexe(tmp,ok);
01580   if(!ok)
01581         {
01582         context.setValue( new KSValue(i18n("Err")));
01583         return false;
01584         }
01585   double imag=imag_complexe(tmp,ok);
01586   if(!ok)
01587         {
01588         context.setValue( new KSValue(i18n("Err")));
01589         return false;
01590         }
01591   tmp=kspreadfunc_create_complex(real,-imag);
01592 
01593   double result=KGlobal::locale()->readNumber(tmp, &ok);
01594   if(ok)
01595         {
01596         context.setValue( new KSValue(result));
01597         return true;
01598         }
01599   context.setValue( new KSValue(tmp));
01600 
01601   return true;
01602 }
01603 
01604 // Function: IMARGUMENT
01605 bool kspreadfunc_imargument( KSContext& context )
01606 {
01607   QValueList<KSValue::Ptr>& args = context.value()->listValue();
01608 
01609   if ( !KSUtil::checkArgumentsCount( context,1, "IMARGUMENT",true ) )
01610     return false;
01611   QString tmp;
01612   if ( !KSUtil::checkType( context, args[0], KSValue::StringType, true ) )
01613         {
01614         if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01615                 return false;
01616         tmp=KGlobal::locale()->formatNumber(args[0]->doubleValue());
01617         }
01618   else
01619         {
01620         tmp=args[0]->stringValue();
01621         }
01622   bool ok;
01623   double real=real_complexe(tmp,ok);
01624   if(!ok)
01625         {
01626         context.setValue( new KSValue(i18n("Err")));
01627         return false;
01628         }
01629   double imag=imag_complexe(tmp,ok);
01630   if(!ok)
01631         {
01632         context.setValue( new KSValue(i18n("Err")));
01633         return false;
01634         }
01635   if(imag==0)
01636         {
01637         context.setValue( new KSValue(i18n("#Div/0")));
01638         return true;
01639         }
01640   double arg=atan2(imag,real);
01641 
01642   context.setValue( new KSValue(arg));
01643 
01644   return true;
01645 }
01646 
01647 // Function: IMABS
01648 bool kspreadfunc_imabs( KSContext& context )
01649 {
01650   QValueList<KSValue::Ptr>& args = context.value()->listValue();
01651 
01652   if ( !KSUtil::checkArgumentsCount( context,1, "IMABS",true ) )
01653     return false;
01654   QString tmp;
01655   if ( !KSUtil::checkType( context, args[0], KSValue::StringType, true ) )
01656         {
01657         if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01658                 return false;
01659         tmp=KGlobal::locale()->formatNumber(args[0]->doubleValue());
01660         }
01661   else
01662         {
01663         tmp=args[0]->stringValue();
01664         }
01665   bool ok;
01666   double real=real_complexe(tmp,ok);
01667   if(!ok)
01668         {
01669         context.setValue( new KSValue(i18n("Err")));
01670         return false;
01671         }
01672   double imag=imag_complexe(tmp,ok);
01673   if(!ok)
01674         {
01675         context.setValue( new KSValue(i18n("Err")));
01676         return false;
01677         }
01678   double arg=sqrt(pow(imag,2)+pow(real,2));
01679 
01680   context.setValue( new KSValue(arg));
01681 
01682   return true;
01683 }
01684 
01685 // Function: IMCOS
01686 bool kspreadfunc_imcos( KSContext& context )
01687 {
01688   QValueList<KSValue::Ptr>& args = context.value()->listValue();
01689 
01690   if ( !KSUtil::checkArgumentsCount( context,1, "IMCOS",true ) )
01691     return false;
01692   QString tmp;
01693   if ( !KSUtil::checkType( context, args[0], KSValue::StringType, true ) )
01694         {
01695         if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01696                 return false;
01697         tmp=KGlobal::locale()->formatNumber(args[0]->doubleValue());
01698         }
01699   else
01700         {
01701         tmp=args[0]->stringValue();
01702         }
01703   bool ok;
01704   double real=real_complexe(tmp,ok);
01705   if(!ok)
01706         {
01707         context.setValue( new KSValue(i18n("Err")));
01708         return false;
01709         }
01710   double imag=imag_complexe(tmp,ok);
01711   if(!ok)
01712         {
01713         context.setValue( new KSValue(i18n("Err")));
01714         return false;
01715         }
01716   double imag_res=sin(real)*sinh(imag);
01717   double real_res=cos(real)*cosh(imag);
01718 
01719 
01720   tmp=kspreadfunc_create_complex(real_res,-imag_res);
01721 
01722   double result=KGlobal::locale()->readNumber(tmp, &ok);
01723   if(ok)
01724         {
01725         context.setValue( new KSValue(result));
01726         return true;
01727         }
01728   context.setValue( new KSValue(tmp));
01729 
01730   return true;
01731 }
01732 
01733 // Function: IMSIN
01734 bool kspreadfunc_imsin( KSContext& context )
01735 {
01736   QValueList<KSValue::Ptr>& args = context.value()->listValue();
01737 
01738   if ( !KSUtil::checkArgumentsCount( context,1, "IMSIN",true ) )
01739     return false;
01740   QString tmp;
01741   if ( !KSUtil::checkType( context, args[0], KSValue::StringType, true ) )
01742         {
01743         if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01744                 return false;
01745         tmp=KGlobal::locale()->formatNumber(args[0]->doubleValue());
01746         }
01747   else
01748         {
01749         tmp=args[0]->stringValue();
01750         }
01751   bool ok;
01752   double real=real_complexe(tmp,ok);
01753   if(!ok)
01754         {
01755         context.setValue( new KSValue(i18n("Err")));
01756         return false;
01757         }
01758   double imag=imag_complexe(tmp,ok);
01759   if(!ok)
01760         {
01761         context.setValue( new KSValue(i18n("Err")));
01762         return false;
01763         }
01764   double imag_res=cos(real)*sinh(imag);
01765   double real_res=sin(real)*cosh(imag);
01766 
01767 
01768   tmp=kspreadfunc_create_complex(real_res,imag_res);
01769 
01770   double result=KGlobal::locale()->readNumber(tmp, &ok);
01771   if(ok)
01772         {
01773         context.setValue( new KSValue(result));
01774         return true;
01775         }
01776   context.setValue( new KSValue(tmp));
01777 
01778   return true;
01779 }
01780 
01781 // Function: IMLN
01782 bool kspreadfunc_imln( KSContext& context )
01783 {
01784   QValueList<KSValue::Ptr>& args = context.value()->listValue();
01785 
01786   if ( !KSUtil::checkArgumentsCount( context,1, "IMLN",true ) )
01787     return false;
01788   QString tmp;
01789   if ( !KSUtil::checkType( context, args[0], KSValue::StringType, true ) )
01790         {
01791         if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01792                 return false;
01793         tmp=KGlobal::locale()->formatNumber(args[0]->doubleValue());
01794         }
01795   else
01796         {
01797         tmp=args[0]->stringValue();
01798         }
01799   bool ok;
01800   double real=real_complexe(tmp,ok);
01801   if(!ok)
01802         {
01803         context.setValue( new KSValue(i18n("Err")));
01804         return false;
01805         }
01806   double imag=imag_complexe(tmp,ok);
01807   if(!ok)
01808         {
01809         context.setValue( new KSValue(i18n("Err")));
01810         return false;
01811         }
01812 
01813 
01814   double arg=sqrt(pow(imag,2)+pow(real,2));
01815   double real_res=log(arg);
01816   double imag_res=atan(imag/real);
01817   tmp=kspreadfunc_create_complex(real_res,imag_res);
01818 
01819   double result=KGlobal::locale()->readNumber(tmp, &ok);
01820   if(ok)
01821         {
01822         context.setValue( new KSValue(result));
01823         return true;
01824         }
01825   context.setValue( new KSValue(tmp));
01826   return true;
01827 }
01828 
01829 // Function: IMEXP
01830 bool kspreadfunc_imexp( KSContext& context )
01831 {
01832   QValueList<KSValue::Ptr>& args = context.value()->listValue();
01833 
01834   if ( !KSUtil::checkArgumentsCount( context,1, "IMEXP",true ) )
01835     return false;
01836   QString tmp;
01837   if ( !KSUtil::checkType( context, args[0], KSValue::StringType, true ) )
01838         {
01839         if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01840                 return false;
01841         tmp=KGlobal::locale()->formatNumber(args[0]->doubleValue());
01842         }
01843   else
01844         {
01845         tmp=args[0]->stringValue();
01846         }
01847   bool ok;
01848   double real=real_complexe(tmp,ok);
01849   if(!ok)
01850         {
01851         context.setValue( new KSValue(i18n("Err")));
01852         return false;
01853         }
01854   double imag=imag_complexe(tmp,ok);
01855   if(!ok)
01856         {
01857         context.setValue( new KSValue(i18n("Err")));
01858         return false;
01859         }
01860   double imag_res=exp(real)*sin(imag);
01861   double real_res=exp(real)*cos(imag);
01862 
01863 
01864   tmp=kspreadfunc_create_complex(real_res,imag_res);
01865 
01866   double result=KGlobal::locale()->readNumber(tmp, &ok);
01867   if(ok)
01868         {
01869         context.setValue( new KSValue(result));
01870         return true;
01871         }
01872   context.setValue( new KSValue(tmp));
01873 
01874   return true;
01875 }
01876 
01877 // Function: IMSQRT
01878 bool kspreadfunc_imsqrt( KSContext& context )
01879 {
01880   QValueList<KSValue::Ptr>& args = context.value()->listValue();
01881 
01882   if ( !KSUtil::checkArgumentsCount( context,1, "IMSQRT",true ) )
01883     return false;
01884   QString tmp;
01885   if ( !KSUtil::checkType( context, args[0], KSValue::StringType, true ) )
01886         {
01887         if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01888                 return false;
01889         tmp=KGlobal::locale()->formatNumber(args[0]->doubleValue());
01890         }
01891   else
01892         {
01893         tmp=args[0]->stringValue();
01894         }
01895   bool ok;
01896   double real=real_complexe(tmp,ok);
01897   if(!ok)
01898         {
01899         context.setValue( new KSValue(i18n("Err")));
01900         return false;
01901         }
01902   double imag=imag_complexe(tmp,ok);
01903   if(!ok)
01904         {
01905         context.setValue( new KSValue(i18n("Err")));
01906         return false;
01907         }
01908   double arg=sqrt(sqrt(pow(imag,2)+pow(real,2)));
01909   double angle=atan(imag/real);
01910 
01911   double real_res=arg*cos((angle/2));
01912   double imag_res=arg*sin((angle/2));
01913 
01914   tmp=kspreadfunc_create_complex(real_res,imag_res);
01915 
01916   double result=KGlobal::locale()->readNumber(tmp, &ok);
01917   if(ok)
01918         {
01919         context.setValue( new KSValue(result));
01920         return true;
01921         }
01922   context.setValue( new KSValue(tmp));
01923 
01924   return true;
01925 }
01926 
01927 // Function: IMPOWER
01928 bool kspreadfunc_impower( KSContext& context )
01929 {
01930   QValueList<KSValue::Ptr>& args = context.value()->listValue();
01931 
01932   if ( !KSUtil::checkArgumentsCount( context,2, "IMPOWER",true ) )
01933     return false;
01934   QString tmp;
01935   if ( !KSUtil::checkType( context, args[0], KSValue::StringType, true ) )
01936         {
01937         if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
01938                 return false;
01939         tmp=KGlobal::locale()->formatNumber(args[0]->doubleValue());
01940         }
01941   else
01942         {
01943         tmp=args[0]->stringValue();
01944         }
01945   if ( !KSUtil::checkType( context, args[1], KSValue::IntType, true ) )
01946         return false;
01947 
01948   bool ok;
01949   double real=real_complexe(tmp,ok);
01950   if(!ok)
01951         {
01952         context.setValue( new KSValue(i18n("Err")));
01953         return false;
01954         }
01955   double imag=imag_complexe(tmp,ok);
01956   if(!ok)
01957         {
01958         context.setValue( new KSValue(i18n("Err")));
01959         return false;
01960         }
01961 
01962   double arg=::pow(sqrt(pow(imag,2)+pow(real,2)),args[1]->intValue());
01963   double angle=atan(imag/real);
01964 
01965   double real_res=arg*cos(angle*args[1]->intValue());
01966   double imag_res=arg*sin(angle*args[1]->intValue());
01967 
01968   tmp=kspreadfunc_create_complex(real_res,imag_res);
01969 
01970   double result=KGlobal::locale()->readNumber(tmp, &ok);
01971   if(ok)
01972         {
01973         context.setValue( new KSValue(result));
01974         return true;
01975         }
01976   context.setValue( new KSValue(tmp));
01977 
01978   return true;
01979 }
01980 
01981 
01982 static bool kspreadfunc_imdiv_helper( KSContext& context, QValueList<KSValue::Ptr>& args, QString& result )
01983 {
01984   QValueList<KSValue::Ptr>::Iterator it = args.begin();
01985   QValueList<KSValue::Ptr>::Iterator end = args.end();
01986 
01987   for( ; it != end; ++it )
01988   {
01989     if ( KSUtil::checkType( context, *it, KSValue::ListType, false ) )
01990     {
01991       if ( !kspreadfunc_imdiv_helper( context, (*it)->listValue(), result ) )
01992         return false;
01993     }
01994     else if ( KSUtil::checkType( context, *it, KSValue::StringType, true ) )
01995       {
01996       double imag,real,imag1,real1;
01997       bool ok;
01998       if(!result.isEmpty())
01999         {
02000         imag=imag_complexe(result, ok);
02001         real=real_complexe(result,  ok);
02002         imag1=imag_complexe((*it)->stringValue(), ok);
02003         real1=real_complexe((*it)->stringValue(), ok);
02004         result=kspreadfunc_create_complex((real*real1+imag*imag1)/(real1*real1+imag1*imag1),(real1*imag-real*imag1)/(real1*real1+imag1*imag1));
02005         }
02006       else
02007         {
02008         imag1=imag_complexe((*it)->stringValue(), ok);
02009         real1=real_complexe((*it)->stringValue(), ok);
02010         result=kspreadfunc_create_complex(real1,imag1);
02011         }
02012       }
02013     else if ( KSUtil::checkType( context, *it, KSValue::DoubleType, true ) )
02014       {
02015       double imag,real,imag1,real1;
02016       bool ok;
02017       imag=imag_complexe(result, ok);
02018       real=real_complexe(result,  ok);
02019       imag1=0;
02020       real1=(*it)->doubleValue();
02021       if(!result.isEmpty())
02022         result=kspreadfunc_create_complex((real*real1+imag*imag1)/(real1*real1+imag1*imag1),(real1*imag-real*imag1)/(real1*real1+imag1*imag1));
02023       else
02024         result=kspreadfunc_create_complex(real1,imag1);
02025       }
02026     else
02027       return false;
02028   }
02029 
02030   return true;
02031 }
02032 
02033 // Function: IMDIV
02034 bool kspreadfunc_imdiv( KSContext& context )
02035 {
02036   QString result ;
02037   bool b = kspreadfunc_imdiv_helper( context, context.value()->listValue(), result );
02038   bool ok;
02039   QString tmp;
02040   double val=KGlobal::locale()->readNumber(result, &ok);
02041   if(ok&&b)
02042         context.setValue( new KSValue( val ) );
02043   else if ( b )
02044     context.setValue( new KSValue( result ) );
02045 
02046   return b;
02047 }
02048 
02049 static bool approx_equal_delta (double a, double b)
02050 {
02051   if ( a == b )
02052     return TRUE;
02053   double x = a - b;
02054   return (x < 0.0 ? -x : x)  <  ((a < 0.0 ? -a : a) * DBL_EPSILON);
02055 }
02056 
02057 // Function: DELTA
02058 bool kspreadfunc_delta( KSContext& context )
02059 {
02060   QValueList<KSValue::Ptr> & args = context.value()->listValue();
02061 
02062   short result;
02063   double val1 = 0.0;
02064   double val2 = 0.0;
02065 
02066   if ( !KSUtil::checkArgumentsCount( context, 2, "DELTA", false ) )
02067   {
02068     if ( !KSUtil::checkArgumentsCount( context, 1, "DELTA", true ) )
02069       return false;
02070   }
02071   else
02072   {
02073     kdDebug() << "Here2" << endl;
02074 
02075     if ( !KSUtil::checkType( context, args[1], KSValue::DoubleType, false ) )
02076     {
02077       if ( !KSUtil::checkType( context, args[1], KSValue::BoolType, true ) )
02078         return false;
02079       val2 = ( args[1]->boolValue() ? 1.0 : 0.0 );
02080     }
02081     else
02082       val2 = args[1]->doubleValue();
02083   }
02084 
02085   kdDebug() << "Here1" << endl;
02086 
02087   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, false ) )
02088   {
02089     if ( !KSUtil::checkType( context, args[0], KSValue::BoolType, true ) )
02090       return false;
02091     val1 = ( args[0]->boolValue() ? 1.0 : 0.0 );
02092   }
02093   else
02094     val1 = args[0]->doubleValue();
02095 
02096   kdDebug() << "Here3" << endl;
02097 
02098   if ( approx_equal_delta( val1, val2 ) )
02099     result = 1;
02100   else
02101     result = 0;
02102 
02103   kdDebug() << "Here4" << endl;
02104   context.setValue( new KSValue( result ) );
02105 
02106   return true;
02107 }
02108 
02109 // Function: ERF
02110 bool kspreadfunc_erf( KSContext & context )
02111 {
02112   QValueList<KSValue::Ptr>& args = context.value()->listValue();
02113 
02114   double result = 0.0;
02115 
02116   if ( KSUtil::checkArgumentsCount( context, 2, "ERF", false ) )
02117   {
02118     double lower_limit = args[0]->doubleValue();
02119     double upper_limit = args[1]->doubleValue();
02120     result = erf( upper_limit ) - erf( lower_limit );
02121   }
02122   else
02123   if ( KSUtil::checkArgumentsCount( context, 1, "ERF", false ) )
02124   {
02125     double limit = args[0]->doubleValue();
02126     result = erf( limit );
02127   }
02128   else
02129     return false;
02130 
02131   context.setValue( new KSValue( result ) );
02132 
02133   return true;
02134 }
02135 
02136 // Function: ERFC
02137 bool kspreadfunc_erfc( KSContext & context )
02138 {
02139   QValueList<KSValue::Ptr>& args = context.value()->listValue();
02140 
02141   double result = 0.0;
02142 
02143   if ( KSUtil::checkArgumentsCount( context, 2, "ERFC", false ) )
02144   {
02145     double lower_limit = args[0]->doubleValue();
02146     double upper_limit = args[1]->doubleValue();
02147     result = erfc( upper_limit ) - erfc( lower_limit );
02148   }
02149   else
02150   if ( KSUtil::checkArgumentsCount( context, 1, "ERFC", false ) )
02151   {
02152     double limit = args[0]->doubleValue();
02153     result = erfc( limit );
02154   }
02155   else
02156     return false;
02157 
02158   context.setValue( new KSValue( result ) );
02159 
02160   return true;
02161 }
02162 
02163 // Function: GESTEP
02164 bool kspreadfunc_gestep( KSContext & context )
02165 {
02166   QValueList<KSValue::Ptr> & args = context.value()->listValue();
02167 
02168   short result;
02169   double val1 = 0.0;
02170   double val2 = 0.0;
02171 
02172   if ( !KSUtil::checkArgumentsCount( context, 2, "GESTEP", false ) )
02173   {
02174     if ( !KSUtil::checkArgumentsCount( context, 1, "GESTEP", true ) )
02175       return false;
02176   }
02177   else
02178   {
02179     if ( !KSUtil::checkType( context, args[1], KSValue::DoubleType, false ) )
02180     {
02181       if ( !KSUtil::checkType( context, args[1], KSValue::BoolType, true ) )
02182         return false;
02183       val2 = ( args[1]->boolValue() ? 1.0 : 0.0 );
02184     }
02185     else
02186       val2 = args[1]->doubleValue();
02187   }
02188 
02189   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, false ) )
02190   {
02191     if ( !KSUtil::checkType( context, args[0], KSValue::BoolType, true ) )
02192       return false;
02193     val1 = ( args[0]->boolValue() ? 1.0 : 0.0 );
02194   }
02195   else
02196     val1 = args[0]->doubleValue();
02197 
02198   if ( ( val1 > val2 ) || approx_equal_delta( val1, val2 ) )
02199     result = 1;
02200   else
02201     result = 0;
02202 
02203   context.setValue( new KSValue( result ) );
02204 
02205   return true;
02206 }
02207 
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:10 2006 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003