00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "functions.h"
00025 #include "valuecalc.h"
00026 #include "valueconverter.h"
00027
00028
00029 #include <qmap.h>
00030
00031
00032 #include <kglobal.h>
00033 #include <klocale.h>
00034 #include <math.h>
00035
00036 using namespace KSpread;
00037
00038
00039 Value func_base (valVector args, ValueCalc *calc, FuncExtra *);
00040 Value func_besseli (valVector args, ValueCalc *calc, FuncExtra *);
00041 Value func_besselj (valVector args, ValueCalc *calc, FuncExtra *);
00042 Value func_besselk (valVector args, ValueCalc *calc, FuncExtra *);
00043 Value func_bessely (valVector args, ValueCalc *calc, FuncExtra *);
00044 Value func_bin2dec (valVector args, ValueCalc *calc, FuncExtra *);
00045 Value func_bin2oct (valVector args, ValueCalc *calc, FuncExtra *);
00046 Value func_bin2hex (valVector args, ValueCalc *calc, FuncExtra *);
00047 Value func_complex (valVector args, ValueCalc *calc, FuncExtra *);
00048 Value func_complex_imag (valVector args, ValueCalc *calc, FuncExtra *);
00049 Value func_complex_real (valVector args, ValueCalc *calc, FuncExtra *);
00050 Value func_convert (valVector args, ValueCalc *calc, FuncExtra *);
00051 Value func_dec2hex (valVector args, ValueCalc *calc, FuncExtra *);
00052 Value func_dec2oct (valVector args, ValueCalc *calc, FuncExtra *);
00053 Value func_dec2bin (valVector args, ValueCalc *calc, FuncExtra *);
00054 Value func_delta (valVector args, ValueCalc *calc, FuncExtra *);
00055 Value func_erf (valVector args, ValueCalc *calc, FuncExtra *);
00056 Value func_erfc (valVector args, ValueCalc *calc, FuncExtra *);
00057 Value func_gestep (valVector args, ValueCalc *calc, FuncExtra *);
00058 Value func_hex2dec (valVector args, ValueCalc *calc, FuncExtra *);
00059 Value func_hex2bin (valVector args, ValueCalc *calc, FuncExtra *);
00060 Value func_hex2oct (valVector args, ValueCalc *calc, FuncExtra *);
00061 Value func_imabs (valVector args, ValueCalc *calc, FuncExtra *);
00062 Value func_imargument (valVector args, ValueCalc *calc, FuncExtra *);
00063 Value func_imconjugate (valVector args, ValueCalc *calc, FuncExtra *);
00064 Value func_imcos (valVector args, ValueCalc *calc, FuncExtra *);
00065 Value func_imdiv (valVector args, ValueCalc *calc, FuncExtra *);
00066 Value func_imexp (valVector args, ValueCalc *calc, FuncExtra *);
00067 Value func_imln (valVector args, ValueCalc *calc, FuncExtra *);
00068 Value func_impower (valVector args, ValueCalc *calc, FuncExtra *);
00069 Value func_improduct (valVector args, ValueCalc *calc, FuncExtra *);
00070 Value func_imsin (valVector args, ValueCalc *calc, FuncExtra *);
00071 Value func_imsqrt (valVector args, ValueCalc *calc, FuncExtra *);
00072 Value func_imsub (valVector args, ValueCalc *calc, FuncExtra *);
00073 Value func_imsum (valVector args, ValueCalc *calc, FuncExtra *);
00074 Value func_oct2dec (valVector args, ValueCalc *calc, FuncExtra *);
00075 Value func_oct2bin (valVector args, ValueCalc *calc, FuncExtra *);
00076 Value func_oct2hex (valVector args, ValueCalc *calc, FuncExtra *);
00077
00078
00079 void RegisterEngineeringFunctions()
00080 {
00081 FunctionRepository* repo = FunctionRepository::self();
00082 Function *f;
00083
00084 f = new Function ("BASE", func_base);
00085 f->setParamCount (1, 3);
00086 repo->add (f);
00087 f = new Function ("BESSELI", func_besseli);
00088 f->setParamCount (2);
00089 repo->add (f);
00090 f = new Function ("BESSELJ", func_besselj);
00091 f->setParamCount (2);
00092 repo->add (f);
00093 f = new Function ("BESSELK", func_besselk);
00094 f->setParamCount (2);
00095 repo->add (f);
00096 f = new Function ("BESSELY", func_bessely);
00097 f->setParamCount (2);
00098 repo->add (f);
00099 f = new Function ("BIN2DEC", func_bin2dec);
00100 repo->add (f);
00101 f = new Function ("BIN2OCT", func_bin2oct);
00102 repo->add (f);
00103 f = new Function ("BIN2HEX", func_bin2hex);
00104 repo->add (f);
00105 f = new Function ("COMPLEX", func_complex);
00106 f->setParamCount (2);
00107 repo->add (f);
00108 f = new Function ("CONVERT", func_convert);
00109 f->setParamCount (3);
00110 repo->add (f);
00111 f = new Function ("DEC2HEX", func_dec2hex);
00112 repo->add (f);
00113 f = new Function ("DEC2BIN", func_dec2bin);
00114 repo->add (f);
00115 f = new Function ("DEC2OCT", func_dec2oct);
00116 repo->add (f);
00117 f = new Function ("DELTA", func_delta);
00118 f->setParamCount (1, 2);
00119 repo->add (f);
00120 f = new Function ("ERF", func_erf);
00121 f->setParamCount (2);
00122 repo->add (f);
00123 f = new Function ("ERFC", func_erfc);
00124 f->setParamCount (1, 2);
00125 repo->add (f);
00126 f = new Function ("GESTEP", func_gestep);
00127 f->setParamCount (1, 2);
00128 repo->add (f);
00129 f = new Function ("HEX2BIN", func_hex2bin);
00130 repo->add (f);
00131 f = new Function ("HEX2DEC", func_hex2dec);
00132 repo->add (f);
00133 f = new Function ("HEX2OCT", func_hex2oct);
00134 repo->add (f);
00135 f = new Function ("IMABS", func_imabs);
00136 repo->add (f);
00137 f = new Function ("IMAGINARY", func_complex_imag);
00138 repo->add (f);
00139 f = new Function ("IMARGUMENT", func_imargument);
00140 repo->add (f);
00141 f = new Function ("IMCONJUGATE", func_imconjugate);
00142 repo->add (f);
00143 f = new Function ("IMCOS", func_imcos);
00144 repo->add (f);
00145 f = new Function ("IMDIV", func_imdiv);
00146 f->setParamCount (1, -1);
00147 f->setAcceptArray ();
00148 repo->add (f);
00149 f = new Function ("IMEXP", func_imexp);
00150 repo->add (f);
00151 f = new Function ("IMLN", func_imln);
00152 repo->add (f);
00153 f = new Function ("IMPOWER", func_impower);
00154 f->setParamCount (2);
00155 repo->add (f);
00156 f = new Function ("IMPRODUCT", func_improduct);
00157 f->setParamCount (1, -1);
00158 f->setAcceptArray ();
00159 repo->add (f);
00160 f = new Function ("IMREAL", func_complex_real);
00161 repo->add (f);
00162 f = new Function ("IMSIN", func_imsin);
00163 repo->add (f);
00164 f = new Function ("IMSQRT", func_imsqrt);
00165 repo->add (f);
00166 f = new Function ("IMSUB", func_imsub);
00167 f->setParamCount (1, -1);
00168 f->setAcceptArray ();
00169 repo->add (f);
00170 f = new Function ("IMSUM", func_imsum);
00171 f->setParamCount (1, -1);
00172 f->setAcceptArray ();
00173 repo->add (f);
00174 f = new Function ("OCT2BIN", func_oct2bin);
00175 repo->add (f);
00176 f = new Function ("OCT2DEC", func_oct2dec);
00177 repo->add (f);
00178 f = new Function ("OCT2HEX", func_oct2hex);
00179 repo->add (f);
00180 }
00181
00182
00183 Value func_base (valVector args, ValueCalc *calc, FuncExtra *)
00184 {
00185 int base = 10;
00186 int prec = 0;
00187 if (args.count() > 1)
00188 base = calc->conv()->asInteger (args[1]).asInteger();
00189 if (args.count() == 3)
00190 prec = calc->conv()->asInteger (args[2]).asInteger();
00191
00192 if ((base < 2) || (base > 36))
00193 return Value::errorVALUE();
00194 if (prec < 0) prec = 2;
00195
00196 return calc->base (args[0], base, prec);
00197 }
00198
00199
00200 Value func_besseli (valVector args, ValueCalc *calc, FuncExtra *)
00201 {
00202 Value x = args[0];
00203 Value y = args[1];
00204 return calc->besseli (y, x);
00205 }
00206
00207
00208 Value func_besselj (valVector args, ValueCalc *calc, FuncExtra *)
00209 {
00210 Value x = args[0];
00211 Value y = args[1];
00212 return calc->besselj (y, x);
00213 }
00214
00215
00216 Value func_besselk (valVector args, ValueCalc *calc, FuncExtra *)
00217 {
00218 Value x = args[0];
00219 Value y = args[1];
00220 return calc->besselk (y, x);
00221 }
00222
00223
00224 Value func_bessely (valVector args, ValueCalc *calc, FuncExtra *)
00225 {
00226 Value x = args[0];
00227 Value y = args[1];
00228 return calc->besseln (y, x);
00229 }
00230
00231
00232 Value func_dec2hex (valVector args, ValueCalc *calc, FuncExtra *)
00233 {
00234 return calc->base (args[0], 16);
00235 }
00236
00237
00238 Value func_dec2oct (valVector args, ValueCalc *calc, FuncExtra *)
00239 {
00240 return calc->base (args[0], 8);
00241 }
00242
00243
00244 Value func_dec2bin (valVector args, ValueCalc *calc, FuncExtra *)
00245 {
00246 return calc->base (args[0], 2);
00247 }
00248
00249
00250 Value func_bin2dec (valVector args, ValueCalc *calc, FuncExtra *)
00251 {
00252 return calc->fromBase (args[0], 2);
00253 }
00254
00255
00256 Value func_bin2oct (valVector args, ValueCalc *calc, FuncExtra *)
00257 {
00258 return calc->base (calc->fromBase (args[0], 2), 8);
00259 }
00260
00261
00262 Value func_bin2hex (valVector args, ValueCalc *calc, FuncExtra *)
00263 {
00264 return calc->base (calc->fromBase (args[0], 2), 16);
00265 }
00266
00267
00268 Value func_oct2dec (valVector args, ValueCalc *calc, FuncExtra *)
00269 {
00270 return calc->fromBase (args[0], 8);
00271 }
00272
00273
00274 Value func_oct2bin (valVector args, ValueCalc *calc, FuncExtra *)
00275 {
00276 return calc->base (calc->fromBase (args[0], 8), 2);
00277 }
00278
00279
00280 Value func_oct2hex (valVector args, ValueCalc *calc, FuncExtra *)
00281 {
00282 return calc->base (calc->fromBase (args[0], 8), 16);
00283 }
00284
00285
00286 Value func_hex2dec (valVector args, ValueCalc *calc, FuncExtra *)
00287 {
00288 return calc->fromBase (args[0], 16);
00289 }
00290
00291
00292 Value func_hex2bin (valVector args, ValueCalc *calc, FuncExtra *)
00293 {
00294 return calc->base (calc->fromBase (args[0], 16), 2);
00295 }
00296
00297
00298 Value func_hex2oct (valVector args, ValueCalc *calc, FuncExtra *)
00299 {
00300 return calc->base (calc->fromBase (args[0], 16), 8);
00301 }
00302
00303
00304
00305
00306
00307
00308 static double kspread_convert_prefix( QMap<QString,double> map, QString& unit )
00309 {
00310 if( map.contains( unit ) )
00311 return 1.0;
00312
00313
00314 static QMap<char,double> prefixMap;
00315 if( prefixMap.isEmpty() )
00316 {
00317 prefixMap[ 'E' ] = 1e18;
00318 prefixMap[ 'P' ] = 1e15;
00319 prefixMap[ 'T' ] = 1e12;
00320 prefixMap[ 'G' ] = 1e9;
00321 prefixMap[ 'M' ] = 1e6;
00322 prefixMap[ 'k' ] = 1e3;
00323 prefixMap[ 'h' ] = 1e2;
00324 prefixMap[ 'e' ] = 1e1;
00325 prefixMap[ 'd' ] = 1e1;
00326 prefixMap[ 'c' ] = 1e2;
00327 prefixMap[ 'm' ] = 1e3;
00328 prefixMap[ 'u' ] = 1e6;
00329 prefixMap[ 'n' ] = 1e9;
00330 prefixMap[ 'p' ] = 1e12;
00331 prefixMap[ 'f' ] = 1e15;
00332 prefixMap[ 'a' ] = 1e18;
00333 }
00334
00335
00336 char prefix = unit[0].latin1();
00337 if( prefixMap.contains( prefix ) )
00338 {
00339 unit.remove( 0, 1 );
00340 return prefixMap[ prefix ];
00341 }
00342
00343
00344 return 0.0;
00345 }
00346
00347 static bool kspread_convert_mass( const QString& fromUnit,
00348 const QString& toUnit, double value, double& result )
00349 {
00350 static QMap<QString, double> massMap;
00351
00352
00353 if( massMap.isEmpty() )
00354 {
00355 massMap[ "g" ] = 1.0;
00356 massMap[ "sg" ] = 6.8522050005347800E-05;
00357 massMap[ "lbm" ] = 2.2046229146913400E-03;
00358 massMap[ "u" ] = 6.0221370000000000E23;
00359 massMap[ "ozm" ] = 3.5273971800362700E-02;
00360 massMap[ "stone" ] = 1.574730e-04;
00361 massMap[ "ton" ] = 1.102311e-06;
00362 massMap[ "grain" ] = 1.543236E01;
00363 massMap[ "pweight" ] = 7.054792E-01;
00364 massMap[ "hweight" ] = 1.968413E-05;
00365 massMap[ "shweight" ] = 2.204623E-05;
00366 massMap[ "brton" ] = 9.842065E-07;
00367 }
00368
00369 QString fromU = fromUnit;
00370 QString toU = toUnit;
00371 double fromPrefix = kspread_convert_prefix( massMap, fromU );
00372 double toPrefix = kspread_convert_prefix( massMap, toU );
00373 if( fromPrefix == 0.0 ) return false;
00374 if( toPrefix == 0.0 ) return false;
00375 if( !massMap.contains( fromU ) ) return false;
00376 if( !massMap.contains( toU ) ) return false;
00377
00378 result = value * fromPrefix * massMap[toU] / (massMap[fromU] * toPrefix);
00379
00380 return true;
00381 }
00382
00383
00384 static bool kspread_convert_distance( const QString& fromUnit,
00385 const QString& toUnit, double value, double& result )
00386 {
00387 static QMap<QString, double> distanceMap;
00388
00389
00390 if( distanceMap.isEmpty() )
00391 {
00392 distanceMap[ "m" ] = 1.0;
00393 distanceMap[ "in" ] = 1.0 / 0.0254;
00394 distanceMap[ "ft" ] = 1.0 / (12.0 * 0.0254);
00395 distanceMap[ "yd" ] = 1.0 / (3.0 * 12.0 * 0.0254);
00396 distanceMap[ "mi" ] = 6.2137119223733397e-4;
00397 distanceMap[ "Nmi" ] = 5.3995680345572354e-04;
00398 distanceMap[ "ang" ] = 1e10;
00399 distanceMap[ "parsec" ] = 3.240779e-17;
00400 distanceMap[ "lightyear" ] = 1.057023455773293e-16;
00401 }
00402
00403 QString fromU = fromUnit;
00404 QString toU = toUnit;
00405 double fromPrefix = kspread_convert_prefix( distanceMap, fromU );
00406 double toPrefix = kspread_convert_prefix( distanceMap, toU );
00407 if( fromPrefix == 0.0 ) return false;
00408 if( toPrefix == 0.0 ) return false;
00409 if( !distanceMap.contains( fromU ) ) return false;
00410 if( !distanceMap.contains( toU ) ) return false;
00411
00412 result = value * fromPrefix * distanceMap[toU] / (distanceMap[fromU] * toPrefix);
00413
00414 return true;
00415 }
00416
00417 static bool kspread_convert_pressure( const QString& fromUnit,
00418 const QString& toUnit, double value, double& result )
00419 {
00420 static QMap<QString, double> pressureMap;
00421
00422
00423 if( pressureMap.isEmpty() )
00424 {
00425 pressureMap[ "Pa" ] = 1.0;
00426 pressureMap[ "atm" ] = 0.9869233e-5;
00427 pressureMap[ "mmHg" ] = 0.00750061708;
00428 pressureMap[ "psi" ] = 1 / 6894.754;
00429 pressureMap[ "Torr" ] = 1 / 133.32237;
00430 }
00431
00432 QString fromU = fromUnit;
00433 QString toU = toUnit;
00434 double fromPrefix = kspread_convert_prefix( pressureMap, fromU );
00435 double toPrefix = kspread_convert_prefix( pressureMap, toU );
00436 if( fromPrefix == 0.0 ) return false;
00437 if( toPrefix == 0.0 ) return false;
00438 if( !pressureMap.contains( fromU ) ) return false;
00439 if( !pressureMap.contains( toU ) ) return false;
00440
00441 result = value * fromPrefix * pressureMap[toU] / (pressureMap[fromU] * toPrefix);
00442
00443 return true;
00444 }
00445
00446 static bool kspread_convert_force( const QString& fromUnit,
00447 const QString& toUnit, double value, double& result )
00448 {
00449 static QMap<QString, double> forceMap;
00450
00451
00452 if( forceMap.isEmpty() )
00453 {
00454 forceMap[ "N" ] = 1.0;
00455 forceMap[ "dyn" ] = 1.0e5;
00456 forceMap[ "pond" ] = 1.019716e2;
00457 }
00458
00459 QString fromU = fromUnit;
00460 QString toU = toUnit;
00461 double fromPrefix = kspread_convert_prefix( forceMap, fromU );
00462 double toPrefix = kspread_convert_prefix( forceMap, toU );
00463 if( fromPrefix == 0.0 ) return false;
00464 if( toPrefix == 0.0 ) return false;
00465 if( !forceMap.contains( fromU ) ) return false;
00466 if( !forceMap.contains( toU ) ) return false;
00467
00468 result = value * fromPrefix * forceMap[toU] / (forceMap[fromU] * toPrefix);
00469
00470 return true;
00471 }
00472
00473 static bool kspread_convert_energy( const QString& fromUnit,
00474 const QString& toUnit, double value, double& result )
00475 {
00476 static QMap<QString, double> energyMap;
00477
00478
00479 if( energyMap.isEmpty() )
00480 {
00481 energyMap[ "J" ] = 1.0;
00482 energyMap[ "e" ] = 1.0e7;
00483 energyMap[ "c" ] = 0.239006249473467;
00484 energyMap[ "cal" ] = 0.238846190642017;
00485 energyMap[ "eV" ] = 6.241457e+18;
00486 energyMap[ "HPh" ] = 3.72506111e-7;
00487 energyMap[ "Wh" ] = 0.000277778;
00488 energyMap[ "flb" ] = 23.73042222;
00489 energyMap[ "BTU" ] = 9.47815067349015e-4;
00490 }
00491
00492 QString fromU = fromUnit;
00493 QString toU = toUnit;
00494 double fromPrefix = kspread_convert_prefix( energyMap, fromU );
00495 double toPrefix = kspread_convert_prefix( energyMap, toU );
00496 if( fromPrefix == 0.0 ) return false;
00497 if( toPrefix == 0.0 ) return false;
00498 if( !energyMap.contains( fromU ) ) return false;
00499 if( !energyMap.contains( toU ) ) return false;
00500
00501 result = value * fromPrefix * energyMap[toU] / (energyMap[fromU] * toPrefix);
00502
00503 return true;
00504 }
00505
00506 static bool kspread_convert_power( const QString& fromUnit,
00507 const QString& toUnit, double value, double& result )
00508 {
00509 static QMap<QString, double> powerMap;
00510
00511
00512 if( powerMap.isEmpty() )
00513 {
00514 powerMap[ "W" ] = 1.0;
00515 powerMap[ "HP" ] = 1.341022e-3;
00516 powerMap[ "PS" ] = 1.359622e-3;
00517 }
00518
00519 QString fromU = fromUnit;
00520 QString toU = toUnit;
00521 double fromPrefix = kspread_convert_prefix( powerMap, fromU );
00522 double toPrefix = kspread_convert_prefix( powerMap, toU );
00523 if( fromPrefix == 0.0 ) return false;
00524 if( toPrefix == 0.0 ) return false;
00525 if( !powerMap.contains( fromU ) ) return false;
00526 if( !powerMap.contains( toU ) ) return false;
00527
00528 result = value * fromPrefix * powerMap[toU] / (powerMap[fromU] * toPrefix);
00529
00530 return true;
00531 }
00532
00533 static bool kspread_convert_magnetism( const QString& fromUnit,
00534 const QString& toUnit, double value, double& result )
00535 {
00536 static QMap<QString, double> magnetismMap;
00537
00538
00539 if( magnetismMap.isEmpty() )
00540 {
00541 magnetismMap[ "T" ] = 1.0;
00542 magnetismMap[ "ga" ] = 1.0e4;
00543 }
00544
00545 QString fromU = fromUnit;
00546 QString toU = toUnit;
00547 double fromPrefix = kspread_convert_prefix( magnetismMap, fromU );
00548 double toPrefix = kspread_convert_prefix( magnetismMap, toU );
00549 if( fromPrefix == 0.0 ) return false;
00550 if( toPrefix == 0.0 ) return false;
00551 if( !magnetismMap.contains( fromU ) ) return false;
00552 if( !magnetismMap.contains( toU ) ) return false;
00553
00554 result = value * fromPrefix * magnetismMap[toU] / (magnetismMap[fromU] * toPrefix);
00555
00556 return true;
00557 }
00558
00559 static bool kspread_convert_temperature( const QString& fromUnit,
00560 const QString& toUnit, double value, double& result )
00561 {
00562 static QMap<QString, double> tempFactorMap;
00563 static QMap<QString, double> tempOffsetMap;
00564
00565
00566 if( tempFactorMap.isEmpty() || tempOffsetMap.isEmpty() )
00567 {
00568 tempFactorMap[ "C" ] = 1.0; tempOffsetMap[ "C" ] = 0.0;
00569 tempFactorMap[ "F" ] = 5.0/9.0; tempOffsetMap[ "F" ] = -32.0;
00570 tempFactorMap[ "K" ] = 1.0; tempOffsetMap[ "K" ] = -273.15;
00571 }
00572
00573 if( !tempFactorMap.contains( fromUnit ) ) return false;
00574 if( !tempOffsetMap.contains( fromUnit ) ) return false;
00575 if( !tempFactorMap.contains( toUnit ) ) return false;
00576 if( !tempOffsetMap.contains( toUnit ) ) return false;
00577
00578 result = ( value + tempOffsetMap[ fromUnit ] )* tempFactorMap[ fromUnit ];
00579 result = ( result / tempFactorMap[ toUnit ] ) - tempOffsetMap[ toUnit ];
00580
00581 return true;
00582 }
00583
00584 static bool kspread_convert_volume( const QString& fromUnit,
00585 const QString& toUnit, double value, double& result )
00586 {
00587 static QMap<QString, double> volumeMap;
00588
00589
00590 if( volumeMap.isEmpty() )
00591 {
00592 volumeMap[ "l" ] = 1.0;
00593 volumeMap[ "tsp" ] = 202.84;
00594 volumeMap[ "tbs" ] = 67.6133333333333;
00595 volumeMap[ "oz" ] = 33.8066666666667;
00596 volumeMap[ "cup" ] = 4.22583333333333;
00597 volumeMap[ "pt" ] = 2.11291666666667;
00598 volumeMap[ "qt" ] = 1.05645833333333;
00599 volumeMap[ "gal" ] = 0.26411458333333;
00600 volumeMap[ "m3" ] = 1.0e-3;
00601 volumeMap[ "mi3" ] = 2.3991275857892772e-13;
00602 volumeMap[ "Nmi3" ] = 1.5742621468581148e-13;
00603 volumeMap[ "in3" ] = 6.1023744094732284e1;
00604 volumeMap[ "ft3" ] = 3.5314666721488590e-2;
00605 volumeMap[ "yd3" ] = 1.3079506193143922;
00606 volumeMap[ "barrel" ] = 6.289811E-03;
00607 }
00608
00609 QString fromU = fromUnit;
00610 QString toU = toUnit;
00611 double fromPrefix = kspread_convert_prefix( volumeMap, fromU );
00612 double toPrefix = kspread_convert_prefix( volumeMap, toU );
00613 if( fromPrefix == 0.0 ) return false;
00614 if( toPrefix == 0.0 ) return false;
00615 if( !volumeMap.contains( fromU ) ) return false;
00616 if( !volumeMap.contains( toU ) ) return false;
00617
00618 result = value * fromPrefix * volumeMap[toU] / (volumeMap[fromU] * toPrefix);
00619
00620 return true;
00621 }
00622
00623 static bool kspread_convert_area( const QString& fromUnit,
00624 const QString& toUnit, double value, double& result )
00625 {
00626 static QMap<QString, double> areaMap;
00627
00628
00629 if( areaMap.isEmpty() )
00630 {
00631 areaMap[ "m2" ] = 1.0;
00632 areaMap[ "mi2" ] = 3.8610215854244585e-7;
00633 areaMap[ "Nmi2" ] = 2.9155334959812286e-7;
00634 areaMap[ "in2" ] = 1.5500031000062000e3;
00635 areaMap[ "ft2" ] = 1.0763910416709722e1;
00636 areaMap[ "yd2" ] = 1.0936132983377078;
00637 areaMap[ "acre" ] = 4.046856e3;
00638 areaMap[ "ha" ] = 1.0e4;
00639 }
00640
00641 QString fromU = fromUnit;
00642 QString toU = toUnit;
00643 double fromPrefix = kspread_convert_prefix( areaMap, fromU );
00644 double toPrefix = kspread_convert_prefix( areaMap, toU );
00645 if( fromPrefix == 0.0 ) return false;
00646 if( toPrefix == 0.0 ) return false;
00647 if( !areaMap.contains( fromU ) ) return false;
00648 if( !areaMap.contains( toU ) ) return false;
00649
00650 result = value * fromPrefix * areaMap[toU] / (areaMap[fromU] * toPrefix);
00651
00652 return true;
00653 }
00654
00655 static bool kspread_convert_speed( const QString& fromUnit,
00656 const QString& toUnit, double value, double& result )
00657 {
00658 static QMap<QString, double> speedMap;
00659
00660
00661 if( speedMap.isEmpty() )
00662 {
00663 speedMap[ "m/s" ] = 1.0;
00664 speedMap[ "m/h" ] = 3.6e3;
00665 speedMap[ "mph" ] = 2.2369362920544023;
00666 speedMap[ "kn" ] = 1.9438444924406048;
00667 }
00668
00669 QString fromU = fromUnit;
00670 QString toU = toUnit;
00671 double fromPrefix = kspread_convert_prefix( speedMap, fromU );
00672 double toPrefix = kspread_convert_prefix( speedMap, toU );
00673 if( fromPrefix == 0.0 ) return false;
00674 if( toPrefix == 0.0 ) return false;
00675 if( !speedMap.contains( fromU ) ) return false;
00676 if( !speedMap.contains( toU ) ) return false;
00677
00678 result = value * fromPrefix * speedMap[toU] / (speedMap[fromU] * toPrefix);
00679
00680 return true;
00681 }
00682
00683
00684
00685 Value func_convert (valVector args, ValueCalc *calc, FuncExtra *)
00686 {
00687
00688
00689 double value = calc->conv()->asFloat (args[0]).asFloat ();
00690 QString fromUnit = calc->conv()->asString (args[1]).asString();
00691 QString toUnit = calc->conv()->asString (args[2]).asString();
00692
00693 double result = value;
00694
00695 if( !kspread_convert_mass( fromUnit, toUnit, value, result ) )
00696 if( !kspread_convert_distance( fromUnit, toUnit, value, result ) )
00697 if( !kspread_convert_pressure( fromUnit, toUnit, value, result ) )
00698 if( !kspread_convert_force( fromUnit, toUnit, value, result ) )
00699 if( !kspread_convert_energy( fromUnit, toUnit, value, result ) )
00700 if( !kspread_convert_power( fromUnit, toUnit, value, result ) )
00701 if( !kspread_convert_magnetism( fromUnit, toUnit, value, result ) )
00702 if( !kspread_convert_temperature( fromUnit, toUnit, value, result ) )
00703 if( !kspread_convert_volume( fromUnit, toUnit, value, result ) )
00704 if( !kspread_convert_area( fromUnit, toUnit, value, result ) )
00705 if( !kspread_convert_speed( fromUnit, toUnit, value, result ) )
00706 return Value::errorNA();
00707
00708 return Value (result);
00709 }
00710
00711
00712
00713
00714
00715
00716 static QString func_create_complex( double real,double imag )
00717 {
00718 QString tmp,tmp2;
00719 if(imag ==0)
00720 {
00721 return KGlobal::locale()->formatNumber( real);
00722 }
00723 if(real!=0)
00724 tmp=KGlobal::locale()->formatNumber(real);
00725 else
00726 return KGlobal::locale()->formatNumber(imag)+"i";
00727 if (imag >0)
00728 tmp=tmp+"+"+KGlobal::locale()->formatNumber(imag)+"i";
00729 else
00730 tmp=tmp+KGlobal::locale()->formatNumber(imag)+"i";
00731 return tmp;
00732
00733 }
00734
00735
00736 Value func_complex (valVector args, ValueCalc *calc, FuncExtra *)
00737 {
00738 if (calc->isZero (args[1]))
00739 return args[0];
00740 double re = calc->conv()->asFloat (args[0]).asFloat ();
00741 double im = calc->conv()->asFloat (args[1]).asFloat ();
00742 QString tmp=func_create_complex (re, im);
00743 bool ok;
00744 double result = KGlobal::locale()->readNumber(tmp, &ok);
00745 if (ok)
00746 return Value (result);
00747 return Value (tmp);
00748 }
00749
00750
00751 static double imag_complexe(QString str, bool &ok)
00752 {
00753 QString tmp=str;
00754 if(tmp.find('i')==-1)
00755 {
00756 ok=true;
00757 return 0;
00758 }
00759 else if( tmp.length()==1)
00760 {
00761
00762 ok=true;
00763 return 1;
00764 }
00765 else if( tmp.length()==2 )
00766 {
00767
00768 int pos1;
00769 if((pos1=tmp.find('+'))!=-1&& pos1==0)
00770 {
00771 ok=true;
00772 return 1;
00773 }
00774 else if( (pos1=tmp.find('-'))!=-1 && pos1==0 )
00775 {
00776 ok=true;
00777 return -1;
00778 }
00779 else if(tmp[0].isDigit())
00780 {
00781 ok=true;
00782 return KGlobal::locale()->readNumber(tmp.left(1));
00783 }
00784 else
00785 {
00786 ok=false;
00787 return 0;
00788 }
00789 }
00790 else
00791 {
00792 int pos1,pos2;
00793 if((pos1=tmp.find('i'))!=-1)
00794 {
00795 double val;
00796 QString tmpStr;
00797
00798 if((pos2=tmp.findRev('+'))!=-1 && pos2!=0)
00799 {
00800 if((pos1-pos2)==1)
00801 {
00802 ok=true;
00803 return 1;
00804 }
00805 else
00806 {
00807 tmpStr=tmp.mid(pos2,(pos1-pos2));
00808 val=KGlobal::locale()->readNumber(tmpStr, &ok);
00809 if(!ok)
00810 val=0;
00811 return val;
00812 }
00813 }
00814 else if( (pos2=tmp.findRev('-'))!=-1&& pos2!=0)
00815 {
00816 if((pos1-pos2)==1)
00817 {
00818 ok=true;
00819 return -1;
00820 }
00821 else
00822 {
00823 tmpStr=tmp.mid(pos2,(pos1-pos2));
00824 val=KGlobal::locale()->readNumber(tmpStr, &ok);
00825 if(!ok)
00826 val=0;
00827 return val;
00828 }
00829 }
00830 else
00831 {
00832 tmpStr=tmp.left(pos1);
00833 val=KGlobal::locale()->readNumber(tmpStr, &ok);
00834 if(!ok)
00835 val=0;
00836 return val;
00837 }
00838 }
00839 }
00840 ok=false;
00841 return 0;
00842 }
00843
00844
00845 Value func_complex_imag (valVector args, ValueCalc *calc, FuncExtra *)
00846 {
00847 QString tmp = calc->conv()->asString (args[0]).asString ();
00848 bool good;
00849 double result=imag_complexe(tmp, good);
00850 if (good)
00851 return Value (result);
00852 return Value::errorVALUE();
00853 }
00854
00855
00856 static double real_complexe(QString str, bool &ok)
00857 {
00858 double val;
00859 int pos1,pos2;
00860 QString tmp=str;
00861 QString tmpStr;
00862 if((pos1=tmp.find('i'))==-1)
00863 {
00864 val=KGlobal::locale()->readNumber(tmp, &ok);
00865 if(!ok)
00866 val=0;
00867 return val;
00868 }
00869 else
00870 {
00871 if((pos2=tmp.findRev('-'))!=-1 && pos2!=0)
00872 {
00873 tmpStr=tmp.left(pos2);
00874 val=KGlobal::locale()->readNumber(tmpStr, &ok);
00875 if(!ok)
00876 val=0;
00877 return val;
00878 }
00879 else if((pos2=tmp.findRev('+'))!=-1)
00880 {
00881 tmpStr=tmp.left(pos2);
00882 val=KGlobal::locale()->readNumber(tmpStr, &ok);
00883 if(!ok)
00884 val=0;
00885 return val;
00886 }
00887 else
00888 {
00889 ok=true;
00890 return 0;
00891 }
00892 }
00893
00894 ok=false;
00895 return 0;
00896 }
00897
00898
00899 Value func_complex_real (valVector args, ValueCalc *calc, FuncExtra *)
00900 {
00901 QString tmp = calc->conv()->asString (args[0]).asString ();
00902 bool good;
00903 double result=real_complexe(tmp, good);
00904 if (good)
00905 return Value (result);
00906 return Value::errorVALUE();
00907 }
00908
00909 void ImHelper (ValueCalc *c, Value res, Value val,
00910 double &imag, double &real, double &imag1, double &real1)
00911 {
00912 bool ok;
00913 imag=imag_complexe(res.asString(), ok);
00914 real=real_complexe(res.asString(), ok);
00915 if (val.isString())
00916 {
00917 imag1 = imag_complexe (val.asString(), ok);
00918 real1 = real_complexe (val.asString(), ok);
00919 } else {
00920 imag1=0;
00921 real1=c->conv()->asFloat (val).asFloat();
00922 }
00923 }
00924
00925 void awImSum (ValueCalc *c, Value &res, Value val, Value)
00926 {
00927 double imag,real,imag1,real1;
00928 ImHelper (c, res, val, imag, real, imag1, real1);
00929 res=func_create_complex(real+real1,imag+imag1);
00930 }
00931
00932 void awImSub (ValueCalc *c, Value &res, Value val, Value)
00933 {
00934 double imag,real,imag1,real1;
00935 ImHelper (c, res, val, imag, real, imag1, real1);
00936 res=func_create_complex(real-real1,imag-imag1);
00937 }
00938
00939 void awImMul (ValueCalc *c, Value &res, Value val, Value)
00940 {
00941 double imag,real,imag1,real1;
00942 ImHelper (c, res, val, imag, real, imag1, real1);
00943 res=func_create_complex(real*real1+(imag*imag1)*-1,real*imag1+real1*imag);
00944 }
00945
00946 void awImDiv (ValueCalc *c, Value &res, Value val, Value)
00947 {
00948 double imag,real,imag1,real1;
00949 ImHelper (c, res, val, imag, real, imag1, real1);
00950 res=func_create_complex((real*real1+imag*imag1)/(real1*real1+imag1*imag1),
00951 (real1*imag-real*imag1)/(real1*real1+imag1*imag1));
00952 }
00953
00954
00955 Value func_imsum (valVector args, ValueCalc *calc, FuncExtra *)
00956 {
00957 Value result;
00958 calc->arrayWalk (args, result, awImSum, 0);
00959
00960 bool ok;
00961 QString res = calc->conv()->asString (result).asString();
00962 double val=KGlobal::locale()->readNumber(res, &ok);
00963 if (ok)
00964 return Value (val);
00965 return Value (result);
00966 }
00967
00968
00969 Value func_imsub (valVector args, ValueCalc *calc, FuncExtra *)
00970 {
00971 Value result;
00972 calc->arrayWalk (args, result, awImSub, 0);
00973
00974 bool ok;
00975 QString res = calc->conv()->asString (result).asString();
00976 double val=KGlobal::locale()->readNumber(res, &ok);
00977 if (ok)
00978 return Value (val);
00979 return Value (result);
00980 }
00981
00982
00983 Value func_improduct (valVector args, ValueCalc *calc, FuncExtra *)
00984 {
00985 Value result;
00986 calc->arrayWalk (args, result, awImMul, 0);
00987
00988 bool ok;
00989 QString res = calc->conv()->asString (result).asString();
00990 double val=KGlobal::locale()->readNumber(res, &ok);
00991 if (ok)
00992 return Value (val);
00993 return Value (result);
00994 }
00995
00996
00997 Value func_imdiv (valVector args, ValueCalc *calc, FuncExtra *)
00998 {
00999 Value result;
01000 calc->arrayWalk (args, result, awImDiv, 0);
01001
01002 bool ok;
01003 QString res = calc->conv()->asString (result).asString();
01004 double val=KGlobal::locale()->readNumber(res, &ok);
01005 if (ok)
01006 return Value (val);
01007 return Value (result);
01008 }
01009
01010
01011 Value func_imconjugate (valVector args, ValueCalc *calc, FuncExtra *)
01012 {
01013 QString tmp = calc->conv()->asString (args[0]).asString();
01014 bool ok;
01015 double real=real_complexe(tmp,ok);
01016 if (!ok)
01017 return Value::errorVALUE();
01018 double imag=imag_complexe(tmp,ok);
01019 if(!ok)
01020 return Value::errorVALUE();
01021
01022 tmp=func_create_complex(real,-imag);
01023
01024 double result=KGlobal::locale()->readNumber(tmp, &ok);
01025 if(ok)
01026 return Value (result);
01027
01028 return Value (tmp);
01029 }
01030
01031
01032 Value func_imargument (valVector args, ValueCalc *calc, FuncExtra *)
01033 {
01034 QString tmp = calc->conv()->asString (args[0]).asString();
01035 bool ok;
01036 double real=real_complexe(tmp,ok);
01037 if (!ok)
01038 return Value::errorVALUE();
01039 double imag=imag_complexe(tmp,ok);
01040 if (!ok)
01041 return Value::errorVALUE();
01042 if(imag==0)
01043 return Value::errorDIV0();
01044 double arg=atan2(imag,real);
01045
01046 return Value (arg);
01047 }
01048
01049
01050 Value func_imabs (valVector args, ValueCalc *calc, FuncExtra *)
01051 {
01052 QString tmp = calc->conv()->asString (args[0]).asString();
01053 bool ok;
01054 double real=real_complexe(tmp,ok);
01055 if(!ok)
01056 return Value::errorVALUE();
01057 double imag=imag_complexe(tmp,ok);
01058 if(!ok)
01059 return Value::errorVALUE();
01060 double arg=sqrt(pow(imag,2)+pow(real,2));
01061
01062 return Value (arg);
01063 }
01064
01065
01066 Value func_imcos (valVector args, ValueCalc *calc, FuncExtra *)
01067 {
01068 QString tmp = calc->conv()->asString (args[0]).asString();
01069 bool ok;
01070 double real=real_complexe(tmp,ok);
01071 if(!ok)
01072 return Value::errorVALUE();
01073 double imag=imag_complexe(tmp,ok);
01074 if(!ok)
01075 return Value::errorVALUE();
01076 double imag_res=sin(real)*sinh(imag);
01077 double real_res=cos(real)*cosh(imag);
01078
01079
01080 tmp=func_create_complex(real_res,-imag_res);
01081
01082 double result=KGlobal::locale()->readNumber(tmp, &ok);
01083 if(ok)
01084 return Value (result);
01085
01086 return Value (tmp);
01087 }
01088
01089
01090 Value func_imsin (valVector args, ValueCalc *calc, FuncExtra *)
01091 {
01092 QString tmp = calc->conv()->asString (args[0]).asString();
01093 bool ok;
01094 double real=real_complexe(tmp,ok);
01095 if(!ok)
01096 return Value::errorVALUE();
01097 double imag=imag_complexe(tmp,ok);
01098 if(!ok)
01099 return Value::errorVALUE();
01100 double imag_res=cos(real)*sinh(imag);
01101 double real_res=sin(real)*cosh(imag);
01102
01103
01104 tmp=func_create_complex(real_res,imag_res);
01105
01106 double result=KGlobal::locale()->readNumber(tmp, &ok);
01107 if(ok)
01108 return Value (result);
01109
01110 return Value (tmp);
01111 }
01112
01113
01114 Value func_imln (valVector args, ValueCalc *calc, FuncExtra *)
01115 {
01116 QString tmp = calc->conv()->asString (args[0]).asString();
01117 bool ok;
01118 double real=real_complexe(tmp,ok);
01119 if(!ok)
01120 return Value::errorVALUE();
01121 double imag=imag_complexe(tmp,ok);
01122 if(!ok)
01123 return Value::errorVALUE();
01124
01125 double arg=sqrt(pow(imag,2)+pow(real,2));
01126 double real_res=log(arg);
01127 double imag_res=atan(imag/real);
01128 tmp=func_create_complex(real_res,imag_res);
01129
01130 double result=KGlobal::locale()->readNumber(tmp, &ok);
01131 if(ok)
01132 return Value (result);
01133
01134 return Value (tmp);
01135 }
01136
01137
01138 Value func_imexp (valVector args, ValueCalc *calc, FuncExtra *)
01139 {
01140 QString tmp = calc->conv()->asString (args[0]).asString();
01141 bool ok;
01142 double real=real_complexe(tmp,ok);
01143 if(!ok)
01144 return Value::errorVALUE();
01145 double imag=imag_complexe(tmp,ok);
01146 if(!ok)
01147 return Value::errorVALUE();
01148 double imag_res=exp(real)*sin(imag);
01149 double real_res=exp(real)*cos(imag);
01150
01151
01152 tmp=func_create_complex(real_res,imag_res);
01153
01154 double result=KGlobal::locale()->readNumber(tmp, &ok);
01155 if(ok)
01156 return Value (result);
01157
01158 return Value (tmp);
01159 }
01160
01161
01162 Value func_imsqrt (valVector args, ValueCalc *calc, FuncExtra *)
01163 {
01164 QString tmp = calc->conv()->asString (args[0]).asString();
01165 bool ok;
01166 double real=real_complexe(tmp,ok);
01167 if(!ok)
01168 return Value::errorVALUE();
01169 double imag=imag_complexe(tmp,ok);
01170 if(!ok)
01171 return Value::errorVALUE();
01172 double arg=sqrt(sqrt(pow(imag,2)+pow(real,2)));
01173 double angle=atan(imag/real);
01174
01175 double real_res=arg*cos((angle/2));
01176 double imag_res=arg*sin((angle/2));
01177
01178 tmp=func_create_complex(real_res,imag_res);
01179
01180 double result=KGlobal::locale()->readNumber(tmp, &ok);
01181 if(ok)
01182 return Value (result);
01183
01184 return Value (tmp);
01185 }
01186
01187
01188 Value func_impower (valVector args, ValueCalc *calc, FuncExtra *)
01189 {
01190 QString tmp = calc->conv()->asString (args[0]).asString();
01191 double val2 = calc->conv()->asFloat (args[1]).asFloat();
01192 bool ok;
01193 double real=real_complexe(tmp,ok);
01194 if(!ok)
01195 return Value::errorVALUE();
01196 double imag=imag_complexe(tmp,ok);
01197 if(!ok)
01198 return Value::errorVALUE();
01199
01200 double arg=::pow(sqrt(pow(imag,2)+pow(real,2)),val2);
01201 double angle=atan(imag/real);
01202
01203 double real_res=arg*cos(angle*val2);
01204 double imag_res=arg*sin(angle*val2);
01205
01206 tmp=func_create_complex(real_res,imag_res);
01207
01208 double result=KGlobal::locale()->readNumber(tmp, &ok);
01209 if(ok)
01210 return Value (result);
01211
01212 return Value (tmp);
01213 }
01214
01215
01216 Value func_delta (valVector args, ValueCalc *calc, FuncExtra *)
01217 {
01218 Value val1 = args[0];
01219 Value val2 = 0.0;
01220 if (args.count() == 2)
01221 val2 = args[1];
01222
01223 return Value (calc->approxEqual (val1, val2) ? 1 : 0);
01224 }
01225
01226
01227 Value func_erf (valVector args, ValueCalc *calc, FuncExtra *)
01228 {
01229 if (args.count() == 2)
01230 return calc->sub (calc->erf (args[1]), calc->erf (args[0]));
01231 return calc->erf (args[0]);
01232 }
01233
01234
01235 Value func_erfc (valVector args, ValueCalc *calc, FuncExtra *)
01236 {
01237 if (args.count() == 2)
01238 return calc->sub (calc->erfc (args[1]), calc->erfc (args[0]));
01239 return calc->erfc (args[0]);
01240 }
01241
01242
01243 Value func_gestep (valVector args, ValueCalc *calc, FuncExtra *)
01244 {
01245 Value x = args[0];
01246 Value y = 0.0;
01247 if (args.count() == 2)
01248 y = args[1];
01249
01250 int result = 0;
01251 if (calc->greater (x, y) || calc->approxEqual (x, y))
01252 result = 1;
01253
01254 return Value (result);
01255 }
01256