KOffice – TDE office suite
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1257 lines
37KB

  1. /* This file is part of the KDE project
  2. Copyright (C) 1998-2002 The KSpread Team
  3. www.koffice.org/kspread
  4. Copyright (C) 2005 Tomas Mecir <mecirt@gmail.com>
  5. This library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Library General Public
  7. License as published by the Free Software Foundation; either
  8. version 2 of the License.
  9. This library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Library General Public License for more details.
  13. You should have received a copy of the GNU Library General Public License
  14. along with this library; see the file COPYING.LIB. If not, write to
  15. the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  16. * Boston, MA 02110-1301, USA.
  17. */
  18. // built-in engineering functions
  19. #include "functions.h"
  20. #include "valuecalc.h"
  21. #include "valueconverter.h"
  22. // used by the CONVERT function
  23. #include <tqmap.h>
  24. // these are needed for complex functions, while we handle them in the old way
  25. #include <tdeglobal.h>
  26. #include <tdelocale.h>
  27. #include <math.h>
  28. using namespace KSpread;
  29. // prototypes (sort alphabetically)
  30. Value func_base (valVector args, ValueCalc *calc, FuncExtra *);
  31. Value func_besseli (valVector args, ValueCalc *calc, FuncExtra *);
  32. Value func_besselj (valVector args, ValueCalc *calc, FuncExtra *);
  33. Value func_besselk (valVector args, ValueCalc *calc, FuncExtra *);
  34. Value func_bessely (valVector args, ValueCalc *calc, FuncExtra *);
  35. Value func_bin2dec (valVector args, ValueCalc *calc, FuncExtra *);
  36. Value func_bin2oct (valVector args, ValueCalc *calc, FuncExtra *);
  37. Value func_bin2hex (valVector args, ValueCalc *calc, FuncExtra *);
  38. Value func_complex (valVector args, ValueCalc *calc, FuncExtra *);
  39. Value func_complex_imag (valVector args, ValueCalc *calc, FuncExtra *);
  40. Value func_complex_real (valVector args, ValueCalc *calc, FuncExtra *);
  41. Value func_convert (valVector args, ValueCalc *calc, FuncExtra *);
  42. Value func_dec2hex (valVector args, ValueCalc *calc, FuncExtra *);
  43. Value func_dec2oct (valVector args, ValueCalc *calc, FuncExtra *);
  44. Value func_dec2bin (valVector args, ValueCalc *calc, FuncExtra *);
  45. Value func_delta (valVector args, ValueCalc *calc, FuncExtra *);
  46. Value func_erf (valVector args, ValueCalc *calc, FuncExtra *);
  47. Value func_erfc (valVector args, ValueCalc *calc, FuncExtra *);
  48. Value func_gestep (valVector args, ValueCalc *calc, FuncExtra *);
  49. Value func_hex2dec (valVector args, ValueCalc *calc, FuncExtra *);
  50. Value func_hex2bin (valVector args, ValueCalc *calc, FuncExtra *);
  51. Value func_hex2oct (valVector args, ValueCalc *calc, FuncExtra *);
  52. Value func_imabs (valVector args, ValueCalc *calc, FuncExtra *);
  53. Value func_imargument (valVector args, ValueCalc *calc, FuncExtra *);
  54. Value func_imconjugate (valVector args, ValueCalc *calc, FuncExtra *);
  55. Value func_imcos (valVector args, ValueCalc *calc, FuncExtra *);
  56. Value func_imdiv (valVector args, ValueCalc *calc, FuncExtra *);
  57. Value func_imexp (valVector args, ValueCalc *calc, FuncExtra *);
  58. Value func_imln (valVector args, ValueCalc *calc, FuncExtra *);
  59. Value func_impower (valVector args, ValueCalc *calc, FuncExtra *);
  60. Value func_improduct (valVector args, ValueCalc *calc, FuncExtra *);
  61. Value func_imsin (valVector args, ValueCalc *calc, FuncExtra *);
  62. Value func_imsqrt (valVector args, ValueCalc *calc, FuncExtra *);
  63. Value func_imsub (valVector args, ValueCalc *calc, FuncExtra *);
  64. Value func_imsum (valVector args, ValueCalc *calc, FuncExtra *);
  65. Value func_oct2dec (valVector args, ValueCalc *calc, FuncExtra *);
  66. Value func_oct2bin (valVector args, ValueCalc *calc, FuncExtra *);
  67. Value func_oct2hex (valVector args, ValueCalc *calc, FuncExtra *);
  68. // registers all engineering functions
  69. void RegisterEngineeringFunctions()
  70. {
  71. FunctionRepository* repo = FunctionRepository::self();
  72. Function *f;
  73. f = new Function ("BASE", func_base); // KSpread-specific, like in Quattro-Pro
  74. f->setParamCount (1, 3);
  75. repo->add (f);
  76. f = new Function ("BESSELI", func_besseli);
  77. f->setParamCount (2);
  78. repo->add (f);
  79. f = new Function ("BESSELJ", func_besselj);
  80. f->setParamCount (2);
  81. repo->add (f);
  82. f = new Function ("BESSELK", func_besselk);
  83. f->setParamCount (2);
  84. repo->add (f);
  85. f = new Function ("BESSELY", func_bessely);
  86. f->setParamCount (2);
  87. repo->add (f);
  88. f = new Function ("BIN2DEC", func_bin2dec);
  89. repo->add (f);
  90. f = new Function ("BIN2OCT", func_bin2oct);
  91. repo->add (f);
  92. f = new Function ("BIN2HEX", func_bin2hex);
  93. repo->add (f);
  94. f = new Function ("COMPLEX", func_complex);
  95. f->setParamCount (2);
  96. repo->add (f);
  97. f = new Function ("CONVERT", func_convert);
  98. f->setParamCount (3);
  99. repo->add (f);
  100. f = new Function ("DEC2HEX", func_dec2hex);
  101. repo->add (f);
  102. f = new Function ("DEC2BIN", func_dec2bin);
  103. repo->add (f);
  104. f = new Function ("DEC2OCT", func_dec2oct);
  105. repo->add (f);
  106. f = new Function ("DELTA", func_delta);
  107. f->setParamCount (1, 2);
  108. repo->add (f);
  109. f = new Function ("ERF", func_erf);
  110. f->setParamCount (2);
  111. repo->add (f);
  112. f = new Function ("ERFC", func_erfc);
  113. f->setParamCount (1, 2);
  114. repo->add (f);
  115. f = new Function ("GESTEP", func_gestep);
  116. f->setParamCount (1, 2);
  117. repo->add (f);
  118. f = new Function ("HEX2BIN", func_hex2bin);
  119. repo->add (f);
  120. f = new Function ("HEX2DEC", func_hex2dec);
  121. repo->add (f);
  122. f = new Function ("HEX2OCT", func_hex2oct);
  123. repo->add (f);
  124. f = new Function ("IMABS", func_imabs);
  125. repo->add (f);
  126. f = new Function ("IMAGINARY", func_complex_imag);
  127. repo->add (f);
  128. f = new Function ("IMARGUMENT", func_imargument);
  129. repo->add (f);
  130. f = new Function ("IMCONJUGATE", func_imconjugate);
  131. repo->add (f);
  132. f = new Function ("IMCOS", func_imcos);
  133. repo->add (f);
  134. f = new Function ("IMDIV", func_imdiv);
  135. f->setParamCount (1, -1);
  136. f->setAcceptArray ();
  137. repo->add (f);
  138. f = new Function ("IMEXP", func_imexp);
  139. repo->add (f);
  140. f = new Function ("IMLN", func_imln);
  141. repo->add (f);
  142. f = new Function ("IMPOWER", func_impower);
  143. f->setParamCount (2);
  144. repo->add (f);
  145. f = new Function ("IMPRODUCT", func_improduct);
  146. f->setParamCount (1, -1);
  147. f->setAcceptArray ();
  148. repo->add (f);
  149. f = new Function ("IMREAL", func_complex_real);
  150. repo->add (f);
  151. f = new Function ("IMSIN", func_imsin);
  152. repo->add (f);
  153. f = new Function ("IMSQRT", func_imsqrt);
  154. repo->add (f);
  155. f = new Function ("IMSUB", func_imsub);
  156. f->setParamCount (1, -1);
  157. f->setAcceptArray ();
  158. repo->add (f);
  159. f = new Function ("IMSUM", func_imsum);
  160. f->setParamCount (1, -1);
  161. f->setAcceptArray ();
  162. repo->add (f);
  163. f = new Function ("OCT2BIN", func_oct2bin);
  164. repo->add (f);
  165. f = new Function ("OCT2DEC", func_oct2dec);
  166. repo->add (f);
  167. f = new Function ("OCT2HEX", func_oct2hex);
  168. repo->add (f);
  169. }
  170. // Function: BASE
  171. Value func_base (valVector args, ValueCalc *calc, FuncExtra *)
  172. {
  173. int base = 10;
  174. int prec = 0;
  175. if (args.count() > 1)
  176. base = calc->conv()->asInteger (args[1]).asInteger();
  177. if (args.count() == 3)
  178. prec = calc->conv()->asInteger (args[2]).asInteger();
  179. if ((base < 2) || (base > 36))
  180. return Value::errorVALUE();
  181. if (prec < 0) prec = 2;
  182. return calc->base (args[0], base, prec);
  183. }
  184. // Function: BESSELI
  185. Value func_besseli (valVector args, ValueCalc *calc, FuncExtra *)
  186. {
  187. Value x = args[0];
  188. Value y = args[1];
  189. return calc->besseli (y, x);
  190. }
  191. // Function: BESSELJ
  192. Value func_besselj (valVector args, ValueCalc *calc, FuncExtra *)
  193. {
  194. Value x = args[0];
  195. Value y = args[1];
  196. return calc->besselj (y, x);
  197. }
  198. // Function: BESSELK
  199. Value func_besselk (valVector args, ValueCalc *calc, FuncExtra *)
  200. {
  201. Value x = args[0];
  202. Value y = args[1];
  203. return calc->besselk (y, x);
  204. }
  205. // Function: BESSELY
  206. Value func_bessely (valVector args, ValueCalc *calc, FuncExtra *)
  207. {
  208. Value x = args[0];
  209. Value y = args[1];
  210. return calc->besseln (y, x);
  211. }
  212. // Function: DEC2HEX
  213. Value func_dec2hex (valVector args, ValueCalc *calc, FuncExtra *)
  214. {
  215. return calc->base (args[0], 16);
  216. }
  217. // Function: DEC2OCT
  218. Value func_dec2oct (valVector args, ValueCalc *calc, FuncExtra *)
  219. {
  220. return calc->base (args[0], 8);
  221. }
  222. // Function: DEC2BIN
  223. Value func_dec2bin (valVector args, ValueCalc *calc, FuncExtra *)
  224. {
  225. return calc->base (args[0], 2);
  226. }
  227. // Function: BIN2DEC
  228. Value func_bin2dec (valVector args, ValueCalc *calc, FuncExtra *)
  229. {
  230. return calc->fromBase (args[0], 2);
  231. }
  232. // Function: BIN2OCT
  233. Value func_bin2oct (valVector args, ValueCalc *calc, FuncExtra *)
  234. {
  235. return calc->base (calc->fromBase (args[0], 2), 8);
  236. }
  237. // Function: BIN2HEX
  238. Value func_bin2hex (valVector args, ValueCalc *calc, FuncExtra *)
  239. {
  240. return calc->base (calc->fromBase (args[0], 2), 16);
  241. }
  242. // Function: OCT2DEC
  243. Value func_oct2dec (valVector args, ValueCalc *calc, FuncExtra *)
  244. {
  245. return calc->fromBase (args[0], 8);
  246. }
  247. // Function: OCT2BIN
  248. Value func_oct2bin (valVector args, ValueCalc *calc, FuncExtra *)
  249. {
  250. return calc->base (calc->fromBase (args[0], 8), 2);
  251. }
  252. // Function: OCT2HEX
  253. Value func_oct2hex (valVector args, ValueCalc *calc, FuncExtra *)
  254. {
  255. return calc->base (calc->fromBase (args[0], 8), 16);
  256. }
  257. // Function: HEX2DEC
  258. Value func_hex2dec (valVector args, ValueCalc *calc, FuncExtra *)
  259. {
  260. return calc->fromBase (args[0], 16);
  261. }
  262. // Function: HEX2BIN
  263. Value func_hex2bin (valVector args, ValueCalc *calc, FuncExtra *)
  264. {
  265. return calc->base (calc->fromBase (args[0], 16), 2);
  266. }
  267. // Function: HEX2OCT
  268. Value func_hex2oct (valVector args, ValueCalc *calc, FuncExtra *)
  269. {
  270. return calc->base (calc->fromBase (args[0], 16), 8);
  271. }
  272. // check if unit may contain prefix, for example "kPa" is "Pa" with
  273. // return prefix factor found in unit, or 1.0 for no prefix
  274. // also modify the unit, i.e stripping the prefix from it
  275. // example: "kPa" will return 1e3 and change unit into "Pa"
  276. static double kspread_convert_prefix( TQMap<TQString,double> map, TQString& unit )
  277. {
  278. if( map.contains( unit ) )
  279. return 1.0;
  280. // initialize prefix mapping if necessary
  281. static TQMap<char,double> prefixMap;
  282. if( prefixMap.isEmpty() )
  283. {
  284. prefixMap[ 'E' ] = 1e18; // exa
  285. prefixMap[ 'P' ] = 1e15; // peta
  286. prefixMap[ 'T' ] = 1e12; // tera
  287. prefixMap[ 'G' ] = 1e9; // giga
  288. prefixMap[ 'M' ] = 1e6; // mega
  289. prefixMap[ 'k' ] = 1e3; // kilo
  290. prefixMap[ 'h' ] = 1e2; // hecto
  291. prefixMap[ 'e' ] = 1e1; // dekao
  292. prefixMap[ 'd' ] = 1e1; // deci
  293. prefixMap[ 'c' ] = 1e2; // centi
  294. prefixMap[ 'm' ] = 1e3; // milli
  295. prefixMap[ 'u' ] = 1e6; // micro
  296. prefixMap[ 'n' ] = 1e9; // nano
  297. prefixMap[ 'p' ] = 1e12; // pico
  298. prefixMap[ 'f' ] = 1e15; // femto
  299. prefixMap[ 'a' ] = 1e18; // atto
  300. }
  301. // check for possible prefix
  302. char prefix = unit[0].latin1();
  303. if( prefixMap.contains( prefix ) )
  304. {
  305. unit.remove( 0, 1 );
  306. return prefixMap[ prefix ];
  307. }
  308. // fail miserably
  309. return 0.0;
  310. }
  311. static bool kspread_convert_mass( const TQString& fromUnit,
  312. const TQString& toUnit, double value, double& result )
  313. {
  314. static TQMap<TQString, double> massMap;
  315. // first-time initialization
  316. if( massMap.isEmpty() )
  317. {
  318. massMap[ "g" ] = 1.0; // Gram (the reference )
  319. massMap[ "sg" ] = 6.8522050005347800E-05; // Pieces
  320. massMap[ "lbm" ] = 2.2046229146913400E-03; // Pound
  321. massMap[ "u" ] = 6.0221370000000000E23; // U (atomic mass)
  322. massMap[ "ozm" ] = 3.5273971800362700E-02; // Ounce
  323. massMap[ "stone" ] = 1.574730e-04; // Stone
  324. massMap[ "ton" ] = 1.102311e-06; // Ton
  325. massMap[ "grain" ] = 1.543236E01; // Grain
  326. massMap[ "pweight" ] = 7.054792E-01; // Pennyweight
  327. massMap[ "hweight" ] = 1.968413E-05; // Hundredweight
  328. massMap[ "shweight" ] = 2.204623E-05; // Shorthundredweight
  329. massMap[ "brton" ] = 9.842065E-07; // Gross Registered Ton
  330. }
  331. TQString fromU = fromUnit;
  332. TQString toU = toUnit;
  333. double fromPrefix = kspread_convert_prefix( massMap, fromU );
  334. double toPrefix = kspread_convert_prefix( massMap, toU );
  335. if( fromPrefix == 0.0 ) return false;
  336. if( toPrefix == 0.0 ) return false;
  337. if( !massMap.contains( fromU ) ) return false;
  338. if( !massMap.contains( toU ) ) return false;
  339. result = value * fromPrefix * massMap[toU] / (massMap[fromU] * toPrefix);
  340. return true;
  341. }
  342. static bool kspread_convert_distance( const TQString& fromUnit,
  343. const TQString& toUnit, double value, double& result )
  344. {
  345. static TQMap<TQString, double> distanceMap;
  346. // first-time initialization
  347. if( distanceMap.isEmpty() )
  348. {
  349. distanceMap[ "m" ] = 1.0; // meter (the reference)
  350. distanceMap[ "in" ] = 1.0 / 0.0254; // inch
  351. distanceMap[ "ft" ] = 1.0 / (12.0 * 0.0254); // feet
  352. distanceMap[ "yd" ] = 1.0 / (3.0 * 12.0 * 0.0254); // yar
  353. distanceMap[ "mi" ] = 6.2137119223733397e-4; // mile
  354. distanceMap[ "Nmi" ] = 5.3995680345572354e-04; // nautical mile
  355. distanceMap[ "ang" ] = 1e10; // Angstrom
  356. distanceMap[ "parsec" ] = 3.240779e-17; // Parsec
  357. distanceMap[ "lightyear" ] = 1.057023455773293e-16; // lightyear
  358. }
  359. TQString fromU = fromUnit;
  360. TQString toU = toUnit;
  361. double fromPrefix = kspread_convert_prefix( distanceMap, fromU );
  362. double toPrefix = kspread_convert_prefix( distanceMap, toU );
  363. if( fromPrefix == 0.0 ) return false;
  364. if( toPrefix == 0.0 ) return false;
  365. if( !distanceMap.contains( fromU ) ) return false;
  366. if( !distanceMap.contains( toU ) ) return false;
  367. result = value * fromPrefix * distanceMap[toU] / (distanceMap[fromU] * toPrefix);
  368. return true;
  369. }
  370. static bool kspread_convert_pressure( const TQString& fromUnit,
  371. const TQString& toUnit, double value, double& result )
  372. {
  373. static TQMap<TQString, double> pressureMap;
  374. // first-time initialization
  375. if( pressureMap.isEmpty() )
  376. {
  377. pressureMap[ "Pa" ] = 1.0;
  378. pressureMap[ "atm" ] = 0.9869233e-5;
  379. pressureMap[ "mmHg" ] = 0.00750061708;
  380. pressureMap[ "psi" ] = 1 / 6894.754;
  381. pressureMap[ "Torr" ] = 1 / 133.32237;
  382. }
  383. TQString fromU = fromUnit;
  384. TQString toU = toUnit;
  385. double fromPrefix = kspread_convert_prefix( pressureMap, fromU );
  386. double toPrefix = kspread_convert_prefix( pressureMap, toU );
  387. if( fromPrefix == 0.0 ) return false;
  388. if( toPrefix == 0.0 ) return false;
  389. if( !pressureMap.contains( fromU ) ) return false;
  390. if( !pressureMap.contains( toU ) ) return false;
  391. result = value * fromPrefix * pressureMap[toU] / (pressureMap[fromU] * toPrefix);
  392. return true;
  393. }
  394. static bool kspread_convert_force( const TQString& fromUnit,
  395. const TQString& toUnit, double value, double& result )
  396. {
  397. static TQMap<TQString, double> forceMap;
  398. // first-time initialization
  399. if( forceMap.isEmpty() )
  400. {
  401. forceMap[ "N" ] = 1.0; // Newton (reference)
  402. forceMap[ "dyn" ] = 1.0e5; // dyn
  403. forceMap[ "pond" ] = 1.019716e2; // pond
  404. }
  405. TQString fromU = fromUnit;
  406. TQString toU = toUnit;
  407. double fromPrefix = kspread_convert_prefix( forceMap, fromU );
  408. double toPrefix = kspread_convert_prefix( forceMap, toU );
  409. if( fromPrefix == 0.0 ) return false;
  410. if( toPrefix == 0.0 ) return false;
  411. if( !forceMap.contains( fromU ) ) return false;
  412. if( !forceMap.contains( toU ) ) return false;
  413. result = value * fromPrefix * forceMap[toU] / (forceMap[fromU] * toPrefix);
  414. return true;
  415. }
  416. static bool kspread_convert_energy( const TQString& fromUnit,
  417. const TQString& toUnit, double value, double& result )
  418. {
  419. static TQMap<TQString, double> energyMap;
  420. // first-time initialization
  421. if( energyMap.isEmpty() )
  422. {
  423. energyMap[ "J" ] = 1.0; // Joule (the reference)
  424. energyMap[ "e" ] = 1.0e7; //erg
  425. energyMap[ "c" ] = 0.239006249473467; // thermodynamical calorie
  426. energyMap[ "cal" ] = 0.238846190642017; // calorie
  427. energyMap[ "eV" ] = 6.241457e+18; // electronvolt
  428. energyMap[ "HPh" ] = 3.72506111e-7; // horsepower-hour
  429. energyMap[ "Wh" ] = 0.000277778; // watt-hour
  430. energyMap[ "flb" ] = 23.73042222;
  431. energyMap[ "BTU" ] = 9.47815067349015e-4; // British Thermal Unit
  432. }
  433. TQString fromU = fromUnit;
  434. TQString toU = toUnit;
  435. double fromPrefix = kspread_convert_prefix( energyMap, fromU );
  436. double toPrefix = kspread_convert_prefix( energyMap, toU );
  437. if( fromPrefix == 0.0 ) return false;
  438. if( toPrefix == 0.0 ) return false;
  439. if( !energyMap.contains( fromU ) ) return false;
  440. if( !energyMap.contains( toU ) ) return false;
  441. result = value * fromPrefix * energyMap[toU] / (energyMap[fromU] * toPrefix);
  442. return true;
  443. }
  444. static bool kspread_convert_power( const TQString& fromUnit,
  445. const TQString& toUnit, double value, double& result )
  446. {
  447. static TQMap<TQString, double> powerMap;
  448. // first-time initialization
  449. if( powerMap.isEmpty() )
  450. {
  451. powerMap[ "W" ] = 1.0; // Watt (the reference)
  452. powerMap[ "HP" ] = 1.341022e-3; // Horsepower
  453. powerMap[ "PS" ] = 1.359622e-3; // Pferdestärke (German)
  454. }
  455. TQString fromU = fromUnit;
  456. TQString toU = toUnit;
  457. double fromPrefix = kspread_convert_prefix( powerMap, fromU );
  458. double toPrefix = kspread_convert_prefix( powerMap, toU );
  459. if( fromPrefix == 0.0 ) return false;
  460. if( toPrefix == 0.0 ) return false;
  461. if( !powerMap.contains( fromU ) ) return false;
  462. if( !powerMap.contains( toU ) ) return false;
  463. result = value * fromPrefix * powerMap[toU] / (powerMap[fromU] * toPrefix);
  464. return true;
  465. }
  466. static bool kspread_convert_magnetism( const TQString& fromUnit,
  467. const TQString& toUnit, double value, double& result )
  468. {
  469. static TQMap<TQString, double> magnetismMap;
  470. // first-time initialization
  471. if( magnetismMap.isEmpty() )
  472. {
  473. magnetismMap[ "T" ] = 1.0; // Tesla (the reference)
  474. magnetismMap[ "ga" ] = 1.0e4; // Gauss
  475. }
  476. TQString fromU = fromUnit;
  477. TQString toU = toUnit;
  478. double fromPrefix = kspread_convert_prefix( magnetismMap, fromU );
  479. double toPrefix = kspread_convert_prefix( magnetismMap, toU );
  480. if( fromPrefix == 0.0 ) return false;
  481. if( toPrefix == 0.0 ) return false;
  482. if( !magnetismMap.contains( fromU ) ) return false;
  483. if( !magnetismMap.contains( toU ) ) return false;
  484. result = value * fromPrefix * magnetismMap[toU] / (magnetismMap[fromU] * toPrefix);
  485. return true;
  486. }
  487. static bool kspread_convert_temperature( const TQString& fromUnit,
  488. const TQString& toUnit, double value, double& result )
  489. {
  490. static TQMap<TQString, double> tempFactorMap;
  491. static TQMap<TQString, double> tempOffsetMap;
  492. // first-time initialization
  493. if( tempFactorMap.isEmpty() || tempOffsetMap.isEmpty() )
  494. {
  495. tempFactorMap[ "C" ] = 1.0; tempOffsetMap[ "C" ] = 0.0;
  496. tempFactorMap[ "F" ] = 5.0/9.0; tempOffsetMap[ "F" ] = -32.0;
  497. tempFactorMap[ "K" ] = 1.0; tempOffsetMap[ "K" ] = -273.15;
  498. }
  499. if( !tempFactorMap.contains( fromUnit ) ) return false;
  500. if( !tempOffsetMap.contains( fromUnit ) ) return false;
  501. if( !tempFactorMap.contains( toUnit ) ) return false;
  502. if( !tempOffsetMap.contains( toUnit ) ) return false;
  503. result = ( value + tempOffsetMap[ fromUnit ] )* tempFactorMap[ fromUnit ];
  504. result = ( result / tempFactorMap[ toUnit ] ) - tempOffsetMap[ toUnit ];
  505. return true;
  506. }
  507. static bool kspread_convert_volume( const TQString& fromUnit,
  508. const TQString& toUnit, double value, double& result )
  509. {
  510. static TQMap<TQString, double> volumeMap;
  511. // first-time initialization
  512. if( volumeMap.isEmpty() )
  513. {
  514. volumeMap[ "l" ] = 1.0; // Liter (the reference)
  515. volumeMap[ "tsp" ] = 202.84; // teaspoon
  516. volumeMap[ "tbs" ] = 67.6133333333333; // sheetspoon
  517. volumeMap[ "oz" ] = 33.8066666666667; // ounce liquid
  518. volumeMap[ "cup" ] = 4.22583333333333; // cup
  519. volumeMap[ "pt" ] = 2.11291666666667; // pint
  520. volumeMap[ "qt" ] = 1.05645833333333; // quart
  521. volumeMap[ "gal" ] = 0.26411458333333; // gallone
  522. volumeMap[ "m3" ] = 1.0e-3; // cubic meter
  523. volumeMap[ "mi3" ] = 2.3991275857892772e-13; // cubic mile
  524. volumeMap[ "Nmi3" ] = 1.5742621468581148e-13; // cubic Nautical mile
  525. volumeMap[ "in3" ] = 6.1023744094732284e1; // cubic inch
  526. volumeMap[ "ft3" ] = 3.5314666721488590e-2; // cubic foot
  527. volumeMap[ "yd3" ] = 1.3079506193143922; // cubic yard
  528. volumeMap[ "barrel" ] = 6.289811E-03; // barrel
  529. }
  530. TQString fromU = fromUnit;
  531. TQString toU = toUnit;
  532. double fromPrefix = kspread_convert_prefix( volumeMap, fromU );
  533. double toPrefix = kspread_convert_prefix( volumeMap, toU );
  534. if( fromPrefix == 0.0 ) return false;
  535. if( toPrefix == 0.0 ) return false;
  536. if( !volumeMap.contains( fromU ) ) return false;
  537. if( !volumeMap.contains( toU ) ) return false;
  538. result = value * fromPrefix * volumeMap[toU] / (volumeMap[fromU] * toPrefix);
  539. return true;
  540. }
  541. static bool kspread_convert_area( const TQString& fromUnit,
  542. const TQString& toUnit, double value, double& result )
  543. {
  544. static TQMap<TQString, double> areaMap;
  545. // first-time initialization
  546. if( areaMap.isEmpty() )
  547. {
  548. areaMap[ "m2" ] = 1.0; // square meter (the reference)
  549. areaMap[ "mi2" ] = 3.8610215854244585e-7; // square mile
  550. areaMap[ "Nmi2" ] = 2.9155334959812286e-7; // square Nautical mile
  551. areaMap[ "in2" ] = 1.5500031000062000e3; // square inch
  552. areaMap[ "ft2" ] = 1.0763910416709722e1; // square foot
  553. areaMap[ "yd2" ] = 1.0936132983377078; // square yard
  554. areaMap[ "acre" ] = 4.046856e3; // acre
  555. areaMap[ "ha" ] = 1.0e4; // hectare
  556. }
  557. TQString fromU = fromUnit;
  558. TQString toU = toUnit;
  559. double fromPrefix = kspread_convert_prefix( areaMap, fromU );
  560. double toPrefix = kspread_convert_prefix( areaMap, toU );
  561. if( fromPrefix == 0.0 ) return false;
  562. if( toPrefix == 0.0 ) return false;
  563. if( !areaMap.contains( fromU ) ) return false;
  564. if( !areaMap.contains( toU ) ) return false;
  565. result = value * fromPrefix * areaMap[toU] / (areaMap[fromU] * toPrefix);
  566. return true;
  567. }
  568. static bool kspread_convert_speed( const TQString& fromUnit,
  569. const TQString& toUnit, double value, double& result )
  570. {
  571. static TQMap<TQString, double> speedMap;
  572. // first-time initialization
  573. if( speedMap.isEmpty() )
  574. {
  575. speedMap[ "m/s" ] = 1.0; // meters per second (the reference)
  576. speedMap[ "m/h" ] = 3.6e3; // meters per hour
  577. speedMap[ "mph" ] = 2.2369362920544023; // miles per hour
  578. speedMap[ "kn" ] = 1.9438444924406048; // knot
  579. }
  580. TQString fromU = fromUnit;
  581. TQString toU = toUnit;
  582. double fromPrefix = kspread_convert_prefix( speedMap, fromU );
  583. double toPrefix = kspread_convert_prefix( speedMap, toU );
  584. if( fromPrefix == 0.0 ) return false;
  585. if( toPrefix == 0.0 ) return false;
  586. if( !speedMap.contains( fromU ) ) return false;
  587. if( !speedMap.contains( toU ) ) return false;
  588. result = value * fromPrefix * speedMap[toU] / (speedMap[fromU] * toPrefix);
  589. return true;
  590. }
  591. // Function: CONVERT
  592. Value func_convert (valVector args, ValueCalc *calc, FuncExtra *)
  593. {
  594. // This function won't support arbitrary precision.
  595. double value = calc->conv()->asFloat (args[0]).asFloat ();
  596. TQString fromUnit = calc->conv()->asString (args[1]).asString();
  597. TQString toUnit = calc->conv()->asString (args[2]).asString();
  598. double result = value;
  599. if( !kspread_convert_mass( fromUnit, toUnit, value, result ) )
  600. if( !kspread_convert_distance( fromUnit, toUnit, value, result ) )
  601. if( !kspread_convert_pressure( fromUnit, toUnit, value, result ) )
  602. if( !kspread_convert_force( fromUnit, toUnit, value, result ) )
  603. if( !kspread_convert_energy( fromUnit, toUnit, value, result ) )
  604. if( !kspread_convert_power( fromUnit, toUnit, value, result ) )
  605. if( !kspread_convert_magnetism( fromUnit, toUnit, value, result ) )
  606. if( !kspread_convert_temperature( fromUnit, toUnit, value, result ) )
  607. if( !kspread_convert_volume( fromUnit, toUnit, value, result ) )
  608. if( !kspread_convert_area( fromUnit, toUnit, value, result ) )
  609. if( !kspread_convert_speed( fromUnit, toUnit, value, result ) )
  610. return Value::errorNA();
  611. return Value (result);
  612. }
  613. // functions operating over complex numbers ...
  614. // these may eventually end up being merged into ValueCalc and friends
  615. // then complex numbers will be handled transparently in most functions
  616. static TQString func_create_complex( double real,double imag )
  617. {
  618. TQString tmp,tmp2;
  619. if(imag ==0)
  620. {
  621. return TDEGlobal::locale()->formatNumber( real);
  622. }
  623. if(real!=0)
  624. tmp=TDEGlobal::locale()->formatNumber(real);
  625. else
  626. return TDEGlobal::locale()->formatNumber(imag)+"i";
  627. if (imag >0)
  628. tmp=tmp+"+"+TDEGlobal::locale()->formatNumber(imag)+"i";
  629. else
  630. tmp=tmp+TDEGlobal::locale()->formatNumber(imag)+"i";
  631. return tmp;
  632. }
  633. // Function: COMPLEX
  634. Value func_complex (valVector args, ValueCalc *calc, FuncExtra *)
  635. {
  636. if (calc->isZero (args[1]))
  637. return args[0];
  638. double re = calc->conv()->asFloat (args[0]).asFloat ();
  639. double im = calc->conv()->asFloat (args[1]).asFloat ();
  640. TQString tmp=func_create_complex (re, im);
  641. bool ok;
  642. double result = TDEGlobal::locale()->readNumber(tmp, &ok);
  643. if (ok)
  644. return Value (result);
  645. return Value (tmp);
  646. }
  647. static double imag_complexe(TQString str, bool &ok)
  648. {
  649. TQString tmp=str;
  650. if(tmp.find('i')==-1)
  651. { //not a complex
  652. ok=true;
  653. return 0;
  654. }
  655. else if( tmp.length()==1)
  656. {
  657. // i
  658. ok=true;
  659. return 1;
  660. }
  661. else if( tmp.length()==2 )
  662. {
  663. //-i,+i,
  664. int pos1;
  665. if((pos1=tmp.find('+'))!=-1&& pos1==0)
  666. {
  667. ok=true;
  668. return 1;
  669. }
  670. else if( (pos1=tmp.find('-'))!=-1 && pos1==0 )
  671. {
  672. ok=true;
  673. return -1;
  674. }
  675. else if(tmp[0].isDigit())
  676. { //5i
  677. ok=true;
  678. return TDEGlobal::locale()->readNumber(tmp.left(1));
  679. }
  680. else
  681. {
  682. ok=false;
  683. return 0;
  684. }
  685. }
  686. else
  687. {//12+12i
  688. int pos1,pos2;
  689. if((pos1=tmp.find('i'))!=-1)
  690. {
  691. double val;
  692. TQString tmpStr;
  693. if((pos2=tmp.findRev('+'))!=-1 && pos2!=0)
  694. {
  695. if((pos1-pos2)==1)
  696. {
  697. ok=true;
  698. return 1;
  699. }
  700. else
  701. {
  702. tmpStr=tmp.mid(pos2,(pos1-pos2));
  703. val=TDEGlobal::locale()->readNumber(tmpStr, &ok);
  704. if(!ok)
  705. val=0;
  706. return val;
  707. }
  708. }
  709. else if( (pos2=tmp.findRev('-'))!=-1&& pos2!=0)
  710. {
  711. if((pos1-pos2)==1)
  712. {
  713. ok=true;
  714. return -1;
  715. }
  716. else
  717. {
  718. tmpStr=tmp.mid(pos2,(pos1-pos2));
  719. val=TDEGlobal::locale()->readNumber(tmpStr, &ok);
  720. if(!ok)
  721. val=0;
  722. return val;
  723. }
  724. }
  725. else
  726. {//15.55i
  727. tmpStr=tmp.left(pos1);
  728. val=TDEGlobal::locale()->readNumber(tmpStr, &ok);
  729. if(!ok)
  730. val=0;
  731. return val;
  732. }
  733. }
  734. }
  735. ok=false;
  736. return 0;
  737. }
  738. // Function: IMAGINARY
  739. Value func_complex_imag (valVector args, ValueCalc *calc, FuncExtra *)
  740. {
  741. TQString tmp = calc->conv()->asString (args[0]).asString ();
  742. bool good;
  743. double result=imag_complexe(tmp, good);
  744. if (good)
  745. return Value (result);
  746. return Value::errorVALUE();
  747. }
  748. static double real_complexe(TQString str, bool &ok)
  749. {
  750. double val;
  751. int pos1,pos2;
  752. TQString tmp=str;
  753. TQString tmpStr;
  754. if((pos1=tmp.find('i'))==-1)
  755. { //12.5
  756. val=TDEGlobal::locale()->readNumber(tmp, &ok);
  757. if(!ok)
  758. val=0;
  759. return val;
  760. }
  761. else
  762. { //15-xi
  763. if((pos2=tmp.findRev('-'))!=-1 && pos2!=0)
  764. {
  765. tmpStr=tmp.left(pos2);
  766. val=TDEGlobal::locale()->readNumber(tmpStr, &ok);
  767. if(!ok)
  768. val=0;
  769. return val;
  770. } //15+xi
  771. else if((pos2=tmp.findRev('+'))!=-1)
  772. {
  773. tmpStr=tmp.left(pos2);
  774. val=TDEGlobal::locale()->readNumber(tmpStr, &ok);
  775. if(!ok)
  776. val=0;
  777. return val;
  778. }
  779. else
  780. {
  781. ok=true;
  782. return 0;
  783. }
  784. }
  785. ok=false;
  786. return 0;
  787. }
  788. // Function: IMREAL
  789. Value func_complex_real (valVector args, ValueCalc *calc, FuncExtra *)
  790. {
  791. TQString tmp = calc->conv()->asString (args[0]).asString ();
  792. bool good;
  793. double result=real_complexe(tmp, good);
  794. if (good)
  795. return Value (result);
  796. return Value::errorVALUE();
  797. }
  798. void ImHelper (ValueCalc *c, Value res, Value val,
  799. double &imag, double &real, double &imag1, double &real1)
  800. {
  801. bool ok;
  802. imag=imag_complexe(res.asString(), ok);
  803. real=real_complexe(res.asString(), ok);
  804. if (val.isString())
  805. {
  806. imag1 = imag_complexe (val.asString(), ok);
  807. real1 = real_complexe (val.asString(), ok);
  808. } else {
  809. imag1=0;
  810. real1=c->conv()->asFloat (val).asFloat();
  811. }
  812. }
  813. void awImSum (ValueCalc *c, Value &res, Value val, Value)
  814. {
  815. double imag,real,imag1,real1;
  816. ImHelper (c, res, val, imag, real, imag1, real1);
  817. res=func_create_complex(real+real1,imag+imag1);
  818. }
  819. void awImSub (ValueCalc *c, Value &res, Value val, Value)
  820. {
  821. double imag,real,imag1,real1;
  822. ImHelper (c, res, val, imag, real, imag1, real1);
  823. res=func_create_complex(real-real1,imag-imag1);
  824. }
  825. void awImMul (ValueCalc *c, Value &res, Value val, Value)
  826. {
  827. double imag,real,imag1,real1;
  828. ImHelper (c, res, val, imag, real, imag1, real1);
  829. res=func_create_complex(real*real1+(imag*imag1)*-1,real*imag1+real1*imag);
  830. }
  831. void awImDiv (ValueCalc *c, Value &res, Value val, Value)
  832. {
  833. double imag,real,imag1,real1;
  834. ImHelper (c, res, val, imag, real, imag1, real1);
  835. res=func_create_complex((real*real1+imag*imag1)/(real1*real1+imag1*imag1),
  836. (real1*imag-real*imag1)/(real1*real1+imag1*imag1));
  837. }
  838. // Function: IMSUM
  839. Value func_imsum (valVector args, ValueCalc *calc, FuncExtra *)
  840. {
  841. Value result;
  842. calc->arrayWalk (args, result, awImSum, 0);
  843. bool ok;
  844. TQString res = calc->conv()->asString (result).asString();
  845. double val=TDEGlobal::locale()->readNumber(res, &ok);
  846. if (ok)
  847. return Value (val);
  848. return Value (result);
  849. }
  850. // Function: IMSUB
  851. Value func_imsub (valVector args, ValueCalc *calc, FuncExtra *)
  852. {
  853. Value result;
  854. calc->arrayWalk (args, result, awImSub, 0);
  855. bool ok;
  856. TQString res = calc->conv()->asString (result).asString();
  857. double val=TDEGlobal::locale()->readNumber(res, &ok);
  858. if (ok)
  859. return Value (val);
  860. return Value (result);
  861. }
  862. // Function: IMPRODUCT
  863. Value func_improduct (valVector args, ValueCalc *calc, FuncExtra *)
  864. {
  865. Value result;
  866. calc->arrayWalk (args, result, awImMul, 0);
  867. bool ok;
  868. TQString res = calc->conv()->asString (result).asString();
  869. double val=TDEGlobal::locale()->readNumber(res, &ok);
  870. if (ok)
  871. return Value (val);
  872. return Value (result);
  873. }
  874. // Function: IMDIV
  875. Value func_imdiv (valVector args, ValueCalc *calc, FuncExtra *)
  876. {
  877. Value result;
  878. calc->arrayWalk (args, result, awImDiv, 0);
  879. bool ok;
  880. TQString res = calc->conv()->asString (result).asString();
  881. double val=TDEGlobal::locale()->readNumber(res, &ok);
  882. if (ok)
  883. return Value (val);
  884. return Value (result);
  885. }
  886. // Function: IMCONJUGATE
  887. Value func_imconjugate (valVector args, ValueCalc *calc, FuncExtra *)
  888. {
  889. TQString tmp = calc->conv()->asString (args[0]).asString();
  890. bool ok;
  891. double real=real_complexe(tmp,ok);
  892. if (!ok)
  893. return Value::errorVALUE();
  894. double imag=imag_complexe(tmp,ok);
  895. if(!ok)
  896. return Value::errorVALUE();
  897. tmp=func_create_complex(real,-imag);
  898. double result=TDEGlobal::locale()->readNumber(tmp, &ok);
  899. if(ok)
  900. return Value (result);
  901. return Value (tmp);
  902. }
  903. // Function: IMARGUMENT
  904. Value func_imargument (valVector args, ValueCalc *calc, FuncExtra *)
  905. {
  906. TQString tmp = calc->conv()->asString (args[0]).asString();
  907. bool ok;
  908. double real=real_complexe(tmp,ok);
  909. if (!ok)
  910. return Value::errorVALUE();
  911. double imag=imag_complexe(tmp,ok);
  912. if (!ok)
  913. return Value::errorVALUE();
  914. if(imag==0)
  915. return Value::errorDIV0();
  916. double arg=atan2(imag,real);
  917. return Value (arg);
  918. }
  919. // Function: IMABS
  920. Value func_imabs (valVector args, ValueCalc *calc, FuncExtra *)
  921. {
  922. TQString tmp = calc->conv()->asString (args[0]).asString();
  923. bool ok;
  924. double real=real_complexe(tmp,ok);
  925. if(!ok)
  926. return Value::errorVALUE();
  927. double imag=imag_complexe(tmp,ok);
  928. if(!ok)
  929. return Value::errorVALUE();
  930. double arg=sqrt(pow(imag,2)+pow(real,2));
  931. return Value (arg);
  932. }
  933. // Function: IMCOS
  934. Value func_imcos (valVector args, ValueCalc *calc, FuncExtra *)
  935. {
  936. TQString tmp = calc->conv()->asString (args[0]).asString();
  937. bool ok;
  938. double real=real_complexe(tmp,ok);
  939. if(!ok)
  940. return Value::errorVALUE();
  941. double imag=imag_complexe(tmp,ok);
  942. if(!ok)
  943. return Value::errorVALUE();
  944. double imag_res=sin(real)*sinh(imag);
  945. double real_res=cos(real)*cosh(imag);
  946. tmp=func_create_complex(real_res,-imag_res);
  947. double result=TDEGlobal::locale()->readNumber(tmp, &ok);
  948. if(ok)
  949. return Value (result);
  950. return Value (tmp);
  951. }
  952. // Function: IMSIN
  953. Value func_imsin (valVector args, ValueCalc *calc, FuncExtra *)
  954. {
  955. TQString tmp = calc->conv()->asString (args[0]).asString();
  956. bool ok;
  957. double real=real_complexe(tmp,ok);
  958. if(!ok)
  959. return Value::errorVALUE();
  960. double imag=imag_complexe(tmp,ok);
  961. if(!ok)
  962. return Value::errorVALUE();
  963. double imag_res=cos(real)*sinh(imag);
  964. double real_res=sin(real)*cosh(imag);
  965. tmp=func_create_complex(real_res,imag_res);
  966. double result=TDEGlobal::locale()->readNumber(tmp, &ok);
  967. if(ok)
  968. return Value (result);
  969. return Value (tmp);
  970. }
  971. // Function: IMLN
  972. Value func_imln (valVector args, ValueCalc *calc, FuncExtra *)
  973. {
  974. TQString tmp = calc->conv()->asString (args[0]).asString();
  975. bool ok;
  976. double real=real_complexe(tmp,ok);
  977. if(!ok)
  978. return Value::errorVALUE();
  979. double imag=imag_complexe(tmp,ok);
  980. if(!ok)
  981. return Value::errorVALUE();
  982. double arg=sqrt(pow(imag,2)+pow(real,2));
  983. double real_res=log(arg);
  984. double imag_res=atan(imag/real);
  985. tmp=func_create_complex(real_res,imag_res);
  986. double result=TDEGlobal::locale()->readNumber(tmp, &ok);
  987. if(ok)
  988. return Value (result);
  989. return Value (tmp);
  990. }
  991. // Function: IMEXP
  992. Value func_imexp (valVector args, ValueCalc *calc, FuncExtra *)
  993. {
  994. TQString tmp = calc->conv()->asString (args[0]).asString();
  995. bool ok;
  996. double real=real_complexe(tmp,ok);
  997. if(!ok)
  998. return Value::errorVALUE();
  999. double imag=imag_complexe(tmp,ok);
  1000. if(!ok)
  1001. return Value::errorVALUE();
  1002. double imag_res=exp(real)*sin(imag);
  1003. double real_res=exp(real)*cos(imag);
  1004. tmp=func_create_complex(real_res,imag_res);
  1005. double result=TDEGlobal::locale()->readNumber(tmp, &ok);
  1006. if(ok)
  1007. return Value (result);
  1008. return Value (tmp);
  1009. }
  1010. // Function: IMSQRT
  1011. Value func_imsqrt (valVector args, ValueCalc *calc, FuncExtra *)
  1012. {
  1013. TQString tmp = calc->conv()->asString (args[0]).asString();
  1014. bool ok;
  1015. double real=real_complexe(tmp,ok);
  1016. if(!ok)
  1017. return Value::errorVALUE();
  1018. double imag=imag_complexe(tmp,ok);
  1019. if(!ok)
  1020. return Value::errorVALUE();
  1021. double arg=sqrt(sqrt(pow(imag,2)+pow(real,2)));
  1022. double angle=atan(imag/real);
  1023. double real_res=arg*cos((angle/2));
  1024. double imag_res=arg*sin((angle/2));
  1025. tmp=func_create_complex(real_res,imag_res);
  1026. double result=TDEGlobal::locale()->readNumber(tmp, &ok);
  1027. if(ok)
  1028. return Value (result);
  1029. return Value (tmp);
  1030. }
  1031. // Function: IMPOWER
  1032. Value func_impower (valVector args, ValueCalc *calc, FuncExtra *)
  1033. {
  1034. TQString tmp = calc->conv()->asString (args[0]).asString();
  1035. double val2 = calc->conv()->asFloat (args[1]).asFloat();
  1036. bool ok;
  1037. double real=real_complexe(tmp,ok);
  1038. if(!ok)
  1039. return Value::errorVALUE();
  1040. double imag=imag_complexe(tmp,ok);
  1041. if(!ok)
  1042. return Value::errorVALUE();
  1043. double arg=::pow(sqrt(pow(imag,2)+pow(real,2)),val2);
  1044. double angle=atan(imag/real);
  1045. double real_res=arg*cos(angle*val2);
  1046. double imag_res=arg*sin(angle*val2);
  1047. tmp=func_create_complex(real_res,imag_res);
  1048. double result=TDEGlobal::locale()->readNumber(tmp, &ok);
  1049. if(ok)
  1050. return Value (result);
  1051. return Value (tmp);
  1052. }
  1053. // Function: DELTA
  1054. Value func_delta (valVector args, ValueCalc *calc, FuncExtra *)
  1055. {
  1056. Value val1 = args[0];
  1057. Value val2 = 0.0;
  1058. if (args.count() == 2)
  1059. val2 = args[1];
  1060. return Value (calc->approxEqual (val1, val2) ? 1 : 0);
  1061. }
  1062. // Function: ERF
  1063. Value func_erf (valVector args, ValueCalc *calc, FuncExtra *)
  1064. {
  1065. if (args.count() == 2)
  1066. return calc->sub (calc->erf (args[1]), calc->erf (args[0]));
  1067. return calc->erf (args[0]);
  1068. }
  1069. // Function: ERFC
  1070. Value func_erfc (valVector args, ValueCalc *calc, FuncExtra *)
  1071. {
  1072. if (args.count() == 2)
  1073. return calc->sub (calc->erfc (args[1]), calc->erfc (args[0]));
  1074. return calc->erfc (args[0]);
  1075. }
  1076. // Function: GESTEP
  1077. Value func_gestep (valVector args, ValueCalc *calc, FuncExtra *)
  1078. {
  1079. Value x = args[0];
  1080. Value y = 0.0;
  1081. if (args.count() == 2)
  1082. y = args[1];
  1083. int result = 0;
  1084. if (calc->greater (x, y) || calc->approxEqual (x, y))
  1085. result = 1;
  1086. return Value (result);
  1087. }