1 /********************************************************************
2 This file is part of the abs 0.907 distribution. abs is a spreadsheet
3 with graphical user interface.
4
5 Copyright (C) 1998-2001 Andr� Bertin (Andre.Bertin@ping.be)
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version if in the same spirit as version 2.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 Concact: abs@pi.be
22 http://home.pi.be/bertin/abs.shtml
23
24 *********************************************************************/
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 #include "mathfct.h"
55 #include "y.tab.h"
56 #include "string.h"
57 #include "math.h"
58 #include "cell_vb.h"
59 #include "typedef.h"
60 #include "application.h"
61 #include "interpret.h"
62 #include "gram_ext.h"
63 #include "abv.h"
64 #include "parser_ext.h"
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128 Fct matharrayfct[] =
129 {
130 {"ABS", &vb_ABS, 1, 1, "ABS(number)", "Returns the absolute value of a number"},
131 {"ACOS", &vb_ACOS, 1, 1, NULL, NULL},
132 {"ACOSH", &vb_ACOSH, 1, 1, NULL, NULL},
133 {"ASIN", &vb_ASIN, 1, 1, NULL, NULL},
134 {"ASINH", &vb_ASINH, 1, 1, NULL, NULL},
135 {"ATAN", &vb_ATAN, 1, 1, NULL, NULL},
136 {"ATAN2", &vb_ATAN2, 1, 1, NULL, NULL},
137 {"ATANH", &vb_ATANH, 1, 1, NULL, NULL},
138 {"CEILING", &vb_CEILING, 1, 1, NULL, NULL},
139 {"COMBIN", &vb_COMBIN, 1, 1, NULL, NULL},
140 {"COS", &vb_COS, 1, 1, NULL, NULL},
141 {"COSH", &vb_COSH, 1, 1, NULL, NULL},
142 {"COUNTIF", &vb_COUNTIF, 1, 1, NULL, NULL},
143 {"DEGREES", &vb_DEGREES, 1, 1, NULL, NULL},
144 {"EVEN", &vb_EVEN, 1, 1, NULL, NULL},
145 {"EXP", &vb_EXP, 1, 1, NULL, NULL},
146 {"FACT", &vb_FACT, 1, 1, NULL, NULL},
147 {"FACTDOUBLE", &vb_FACTDOUBLE, 1, 1, NULL, NULL},
148 {"FLOOR", &vb_FLOOR, 1, 1, NULL, NULL},
149 {"GCD", &vb_GCD, 1, 1, NULL, NULL},
150 {"INT", &vb_INT, 1, 1, NULL, NULL},
151 {"LCM", &vb_LCM, 1, 1, NULL, NULL},
152 {"LN", &vb_LN, 1, 1, NULL, NULL},
153 {"LOG10", &vb_LOG10, 1, 1, NULL, NULL},
154 {"LOG", &vb_LOG, 1, 1, NULL, NULL},
155 {"MDETERM", &vb_MDETERM, 1, 1, NULL, NULL},
156 {"MINVERSE", &vb_MINVERSE, 1, 1, NULL, NULL},
157 {"MMULT", &vb_MMULT, 1, 1, NULL, NULL},
158 {"MOD", &vb_MOD, 1, 1, NULL, NULL},
159 {"MROUND", &vb_MROUND, 1, 1, NULL, NULL},
160 {"MULTINOMIAL", &vb_MULTINOMIAL, 1, 1, NULL, NULL},
161 {"ODD", &vb_ODD, 1, 1, NULL, NULL},
162 {"PI", &vb_PI, 1, 1, NULL, NULL},
163 {"POWER", &vb_POWER, 1, 1, NULL, NULL},
164 {"PRODUCT", &vb_PRODUCT, 1, 1, NULL, NULL},
165 {"QUOTIENT", &vb_QUOTIENT, 1, 1, NULL, NULL},
166 {"RADIANS", &vb_RADIANS, 1, 1, NULL, NULL},
167 {"RAND", &vb_RAND, 1, 1, NULL, NULL},
168 {"RANDBETWEEN", &vb_RANDBETWEEN, 1, 1, NULL, NULL},
169 {"ROMAN", &vb_ROMAN, 1, 1, NULL, NULL},
170 {"ROUND", &vb_ROUND, 1, 1, NULL, NULL},
171 {"ROUNDDOWN", &vb_ROUNDDOWN, 1, 1, NULL, NULL},
172 {"ROUNDUP", &vb_ROUNDUP, 1, 1, NULL, NULL},
173 {"SERIESSUM", &vb_SERIESSUM, 1, 1, NULL, NULL},
174 {"SIGN", &vb_SIGN, 1, 1, NULL, NULL},
175 {"SIN", &vb_SIN, 1, 1, NULL, NULL},
176 {"SINH", &vb_SINH, 1, 1, NULL, NULL},
177 {"SQRT", &vb_SQRT, 1, 1, NULL, NULL},
178 {"SQRTPI", &vb_SQRTPI, 1, 1, NULL, NULL},
179 {"SUM", &vb_SUM, 1, 1, NULL, NULL},
180 {"SUMIF", &vb_SUMIF, 1, 1, NULL, NULL},
181 {"SUMPRODUCT", &vb_SUMPRODUCT, 1, 1, NULL, NULL},
182 {"SUMSQ", &vb_SUMSQ, 1, 1, NULL, NULL},
183 {"SUMX2MY2", &vb_SUMX2MY2, 1, 1, NULL, NULL},
184 {"SUMX2PY2", &vb_SUMX2PY2, 1, 1, NULL, NULL},
185 {"SUMXMY2", &vb_SUMXMY2, 1, 1, NULL, NULL},
186 {"TAN", &vb_TAN, 1, 1, NULL, NULL},
187 {"TANH", &vb_TANH, 1, 1, NULL, NULL},
188 {"TRUNC", &vb_TRUNC, 1, 1, NULL, NULL},
189 {NULL, NULL, 0, 0, NULL, NULL},
190 };
191
192
193
194
195
196
197 #ifndef PI
198 #define PI 3.14159265359
199 #endif
200
201 int
makeif(obj value,char * criteria)202 makeif (obj value, char *criteria)
203 {
204 obj val;
205 int doit = 0;
206 char *formula = NULL;
207 int len = 0;
208 int ret = 0;
209
210 if (criteria == NULL)
211 return 0;
212
213 len = strlen (criteria);
214
215 switch (value.type)
216 {
217 case INTEGER:
218 formula = (char *) absmalloc ((len + 20) * sizeof (char), "makeif:formula");
219 sprintf (formula, "%d%s", value.rec.i, criteria);
220 doit = 1;
221 break;
222 case DOUBLE:
223 formula = (char *) absmalloc ((len + 32) * sizeof (char), "makeif:formula");
224 sprintf (formula, "%f%s", value.rec.d, criteria);
225 doit = 1;
226 break;
227 case STRING_CONSTANT:
228 if (value.rec.s == NULL)
229 break;
230 formula = (char *) absmalloc ((len + strlen (value.rec.s) + 8) * sizeof (char), "makeif:formula");
231 sprintf (formula, "\"%s\"=\"%s\"", value.rec.s, criteria);
232 doit = 1;
233 break;
234 }
235 if (doit)
236 {
237 seteqboolean ();
238 val = exint (parseexpression (formula));
239 unseteqboolean ();
240 if (obj2int (val))
241 ret = 1;
242 absfree (formula, "makeif:formula");
243 }
244 return ret;
245 }
246
247
248 obj
vb_ABS(int narg,obj * arg)249 vb_ABS (int narg, obj * arg)
250 {
251 obj o;
252 o.rec.d = abs (obj2double (arg[0]));
253 o.type = DOUBLE;
254 return o;
255 }
256 obj
vb_ACOS(int narg,obj * arg)257 vb_ACOS (int narg, obj * arg)
258 {
259 obj o;
260 o.rec.d = acos (obj2double (arg[0]));
261 o.type = DOUBLE;
262 return o;
263 }
264 obj
vb_ACOSH(int narg,obj * arg)265 vb_ACOSH (int narg, obj * arg)
266 {
267 obj o;
268 o.rec.d = acosh (obj2double (arg[0]));
269 o.type = DOUBLE;
270 return o;
271 }
272 obj
vb_ASIN(int narg,obj * arg)273 vb_ASIN (int narg, obj * arg)
274 {
275 obj o;
276 o.rec.d = asin (obj2double (arg[0]));
277 o.type = DOUBLE;
278 return o;
279 }
280 obj
vb_ASINH(int narg,obj * arg)281 vb_ASINH (int narg, obj * arg)
282 {
283 obj o;
284 o.rec.d = asinh (obj2double (arg[0]));
285 o.type = DOUBLE;
286 return o;
287 }
288 obj
vb_ATAN(int narg,obj * arg)289 vb_ATAN (int narg, obj * arg)
290 {
291 obj o;
292 o.rec.d = atan (obj2double (arg[0]));
293 o.type = DOUBLE;
294 return o;
295 }
296 obj
vb_ATAN2(int narg,obj * arg)297 vb_ATAN2 (int narg, obj * arg)
298 {
299 obj o;
300 o.rec.d = atan2 (obj2double (arg[0]), obj2double (arg[1]));
301 o.type = DOUBLE;
302 return o;
303 }
304 obj
vb_ATANH(int narg,obj * arg)305 vb_ATANH (int narg, obj * arg)
306 {
307 obj o;
308 o.rec.d = atanh (obj2double (arg[0]));
309 o.type = DOUBLE;
310 return o;
311 }
312 obj
vb_CEILING(int narg,obj * arg)313 vb_CEILING (int narg, obj * arg)
314 {
315
316
317
318
319
320
321 obj o;
322 double nombre = obj2double (arg[0]);
323 double multiple = obj2double (arg[1]);
324 double tmp = 0.0;
325 int n = 0;
326
327 if (nombre * multiple > 0)
328 {
329 tmp = multiple;
330 while (fabs (tmp) < fabs (nombre) && n < 1000)
331 {
332 tmp *= fabs (multiple);
333 n++;
334 }
335 tmp /= multiple;
336 }
337
338 o.rec.d = tmp;
339 o.type = DOUBLE;
340 return o;
341 }
342
343 int
fact(int n)344 fact (int n)
345 {
346 int i;
347 int val = 1.0;
348 for (i = 2; i <= n && i < 200; i++)
349 val *= i;
350 return val;
351 }
352
353 obj
vb_COMBIN(int narg,obj * arg)354 vb_COMBIN (int narg, obj * arg)
355 {
356 obj o;
357 int n;
358 int k;
359 double a, b;
360
361 k = obj2int (arg[1]);
362 n = obj2int (arg[0]);
363
364 if (n > 0 && k > 0 && n > k)
365 {
366 a = fact (n);
367 b = fact (k) * fact (n - k);
368 o.rec.d = a / b;
369 }
370 else
371 {
372 o.rec.d = 0;
373 }
374
375 o.type = DOUBLE;
376 return o;
377 }
378
379 obj
vb_COS(int narg,obj * arg)380 vb_COS (int narg, obj * arg)
381 {
382 obj o;
383 o.rec.d = cos (obj2double (arg[0]));
384 o.type = DOUBLE;
385 return o;
386 }
387 obj
vb_COSH(int narg,obj * arg)388 vb_COSH (int narg, obj * arg)
389 {
390 obj o;
391 o.rec.d = cosh (obj2double (arg[0]));
392 o.type = DOUBLE;
393 return o;
394 }
395 obj
vb_COUNTIF(int narg,obj * arg)396 vb_COUNTIF (int narg, obj * arg)
397 {
398 obj o;
399 obj tmp;
400 int i, r, c;
401 int ret = 0;
402 tmpRange *ran;
403 o.type = INTEGER;
404 o.rec.i = 0;
405 if (narg < 2)
406 return o;
407 if (arg[0].type != STRING_CONSTANT && arg[0].type != STRING)
408 return o;
409 if (arg[0].rec.s == NULL)
410 return o;
411
412 for (i = 1; i < narg; i++)
413 {
414 if (arg[i].type == RANGE)
415 {
416 ran = (tmpRange *) arg[i].rec.s;
417 if (ran->wks == NULL)
418 {
419 for (r = ran->r1; r <= ran->r2; r++)
420 for (c = ran->c1; c <= ran->c2; c++)
421 {
422 tmp = get_ovalue (r, c);
423 ret += makeif (tmp, arg[0].rec.s);
424 }
425 }
426 else
427 {
428 for (r = ran->r1; r <= ran->r2; r++)
429 for (c = ran->c1; c <= ran->c2; c++)
430 {
431 tmp = get_ovalue_wks (ran->wks, r, c);
432 ret += makeif (tmp, arg[0].rec.s);
433 }
434 }
435 }
436 else
437 {
438 tmp = id2val (arg[i]);
439 ret += makeif (tmp, arg[0].rec.s);
440 }
441 }
442
443 o.rec.i = ret;
444 return o;
445 }
446
447 obj
vb_DEGREES(int narg,obj * arg)448 vb_DEGREES (int narg, obj * arg)
449 {
450 obj o;
451 o.rec.d = 180.0 / PI * (obj2double (arg[0]));
452 o.type = DOUBLE;
453 return o;
454 }
455 obj
vb_EVEN(int narg,obj * arg)456 vb_EVEN (int narg, obj * arg)
457 {
458 obj o;
459
460 ABVInform ("EVEN not yet implemented");
461 o.type = DOUBLE;
462 return o;
463 }
464
465 obj
vb_EXP(int narg,obj * arg)466 vb_EXP (int narg, obj * arg)
467 {
468 obj o;
469 double x, y;
470
471 x = obj2double (arg[0]);
472 y = obj2double (arg[1]);
473 o.rec.d = pow (x, y);
474 o.type = DOUBLE;
475 return o;
476 }
477 obj
vb_FACT(int narg,obj * arg)478 vb_FACT (int narg, obj * arg)
479 {
480 obj o;
481 o.rec.d = fact (obj2int (arg[0]));
482 o.type = DOUBLE;
483 return o;
484 }
485 obj
vb_FACTDOUBLE(int narg,obj * arg)486 vb_FACTDOUBLE (int narg, obj * arg)
487 {
488 obj o;
489 o.rec.d = fact (obj2int (arg[0]));
490 o.type = DOUBLE;
491 return o;
492 }
493 obj
vb_FLOOR(int narg,obj * arg)494 vb_FLOOR (int narg, obj * arg)
495 {
496 obj o;
497 o.rec.d = floor (obj2double (arg[0]));
498 o.type = DOUBLE;
499 return o;
500 }
501 obj
vb_GCD(int narg,obj * arg)502 vb_GCD (int narg, obj * arg)
503 {
504 obj o;
505 int i;
506 int f = 1;
507 double div = 2;
508 while (f)
509 {
510 for (i = 0; i < narg; i++)
511 {
512 if (fmod (obj2double (arg[0]), div) != 0)
513 f = 0;
514 }
515 div++;
516 }
517 div--;
518 o.rec.d = div;
519 o.type = DOUBLE;
520 return o;
521 }
522
523 obj
vb_INT(int narg,obj * arg)524 vb_INT (int narg, obj * arg)
525 {
526 obj o;
527 double val = obj2double (arg[0]);
528 o.rec.d = rint (val);
529 o.type = DOUBLE;
530 return o;
531 }
532 obj
vb_LCM(int narg,obj * arg)533 vb_LCM (int narg, obj * arg)
534 {
535 obj o;
536
537 ABVInform ("LCM not yet implemented");
538 o.type = DOUBLE;
539 return o;
540 }
541 obj
vb_LN(int narg,obj * arg)542 vb_LN (int narg, obj * arg)
543 {
544 obj o;
545 o.rec.d = log (obj2double (arg[0]));
546 o.type = DOUBLE;
547 return o;
548 }
549 obj
vb_LOG(int narg,obj * arg)550 vb_LOG (int narg, obj * arg)
551 {
552 obj o;
553 o.rec.d = log10 (obj2double (arg[0]));
554 o.type = DOUBLE;
555 return o;
556 }
557 obj
vb_LOG10(int narg,obj * arg)558 vb_LOG10 (int narg, obj * arg)
559 {
560 obj o;
561 o.rec.d = log10 (obj2double (arg[0]));
562 o.type = DOUBLE;
563 return o;
564 }
565 obj
vb_MDETERM(int narg,obj * arg)566 vb_MDETERM (int narg, obj * arg)
567 {
568 obj o;
569
570 ABVInform ("MDETERM not yet implemented");
571 o.type = DOUBLE;
572 return o;
573 }
574 obj
vb_MINVERSE(int narg,obj * arg)575 vb_MINVERSE (int narg, obj * arg)
576 {
577 obj o;
578
579 ABVInform ("MINVERSE not yet implemented");
580 o.type = DOUBLE;
581 return o;
582 }
583 obj
vb_MMULT(int narg,obj * arg)584 vb_MMULT (int narg, obj * arg)
585 {
586 obj o;
587
588 ABVInform ("MMULT not yet implemented");
589 o.type = DOUBLE;
590 return o;
591 }
592 obj
vb_MOD(int narg,obj * arg)593 vb_MOD (int narg, obj * arg)
594 {
595 obj o;
596 o.rec.d = fmod (obj2double (arg[0]), obj2double (arg[1]));
597 o.type = DOUBLE;
598 return o;
599 }
600 obj
vb_MROUND(int narg,obj * arg)601 vb_MROUND (int narg, obj * arg)
602 {
603 obj o;
604
605 ABVInform (" MROUND not yet implemented");
606
607 o.type = DOUBLE;
608 return o;
609 }
610 obj
vb_MULTINOMIAL(int narg,obj * arg)611 vb_MULTINOMIAL (int narg, obj * arg)
612 {
613 obj o;
614
615 ABVInform ("MULTINOMIAL not yet implemented");
616
617 o.type = DOUBLE;
618 return o;
619 }
620 obj
vb_ODD(int narg,obj * arg)621 vb_ODD (int narg, obj * arg)
622 {
623 obj o;
624
625 ABVInform ("ODD not yet implemented");
626 o.type = DOUBLE;
627 return o;
628 }
629 obj
vb_PI(int narg,obj * arg)630 vb_PI (int narg, obj * arg)
631 {
632 obj o;
633 o.rec.d = PI;
634 o.type = DOUBLE;
635 return o;
636 }
637 obj
vb_POWER(int narg,obj * arg)638 vb_POWER (int narg, obj * arg)
639 {
640 obj o;
641 o.rec.d = pow (obj2double (arg[0]), obj2double (arg[1]));
642 o.type = DOUBLE;
643 return o;
644 }
645 obj
vb_PRODUCT(int narg,obj * arg)646 vb_PRODUCT (int narg, obj * arg)
647 {
648 obj o;
649 int r, c;
650 tmpRange *ran;
651 double val = 1;
652 int i;
653 for (i = 0; i < narg; i++)
654 {
655 if (arg[i].type == RANGE)
656 {
657 ran = (tmpRange *) arg[i].rec.s;
658 if (ran->wks == NULL)
659 {
660 for (r = ran->r1; r <= ran->r2; r++)
661 for (c = ran->c1; c <= ran->c2; c++)
662 val *= get_value (r, c);
663 }
664 else
665 {
666 for (r = ran->r1; r <= ran->r2; r++)
667 for (c = ran->c1; c <= ran->c2; c++)
668 val *= get_value_wks (ran->wks, r, c);
669 }
670 }
671 else
672 val *= obj2double (arg[i]);
673 }
674 o.rec.d = val;
675 o.type = DOUBLE;
676 return o;
677 }
678
679 obj
vb_QUOTIENT(int narg,obj * arg)680 vb_QUOTIENT (int narg, obj * arg)
681 {
682 obj o;
683
684 o.rec.d = 0.0;
685 o.type = DOUBLE;
686 return o;
687 }
688
689 obj
vb_RADIANS(int narg,obj * arg)690 vb_RADIANS (int narg, obj * arg)
691 {
692 obj o;
693 o.rec.d = PI / 180.0 * (obj2double (arg[0]));
694 o.type = DOUBLE;
695 return o;
696 }
697 obj
vb_RAND(int narg,obj * arg)698 vb_RAND (int narg, obj * arg)
699 {
700 obj o;
701 o.rec.d = 0.0 + (1.0 * rand () / (RAND_MAX + 1.0));
702 o.type = DOUBLE;
703 return o;
704 }
705 obj
vb_RANDBETWEEN(int narg,obj * arg)706 vb_RANDBETWEEN (int narg, obj * arg)
707 {
708 obj o;
709 double low = obj2double (arg[0]);
710 double up = obj2double (arg[1]);
711
712 o.rec.d = low + (up * rand () / (RAND_MAX + 1.0));
713 o.type = DOUBLE;
714 return o;
715 }
716 obj
vb_ROMAN(int narg,obj * arg)717 vb_ROMAN (int narg, obj * arg)
718 {
719 obj o;
720
721 ABVInform ("ROMAN not yet implemented");
722 o.type = DOUBLE;
723 return o;
724 }
725 obj
vb_ROUND(int narg,obj * arg)726 vb_ROUND (int narg, obj * arg)
727 {
728 obj o;
729 double val = obj2double (arg[0]);
730 double ndeci = 0;
731 int valint;
732 if (narg > 1)
733 ndeci = obj2double (arg[1]);
734
735 if (ndeci >= 0)
736 {
737 valint = rint (val * pow (10, ndeci));
738 val = valint * pow (10, -ndeci);
739 }
740 o.rec.d = val;
741
742 o.type = DOUBLE;
743 return o;
744 }
745 obj
vb_ROUNDDOWN(int narg,obj * arg)746 vb_ROUNDDOWN (int narg, obj * arg)
747 {
748 obj o;
749 double val = obj2double (arg[0]);
750 double ndeci = 0;
751 if (narg > 1)
752 ndeci = obj2double (arg[1]);
753
754 if (ndeci >= 0)
755 {
756 val *= pow (10, ndeci);
757 val = floor (val);
758 val *= pow (10, -ndeci);
759 }
760 o.rec.d = val;
761 o.type = DOUBLE;
762 return o;
763 }
764 obj
vb_ROUNDUP(int narg,obj * arg)765 vb_ROUNDUP (int narg, obj * arg)
766 {
767 obj o;
768 double val = obj2double (arg[0]);
769 double ndeci = 0;
770 if (narg > 1)
771 ndeci = obj2double (arg[1]);
772
773 if (ndeci >= 0)
774 {
775 val *= pow (10, ndeci);
776 val = ceil (val);
777 val *= pow (10, -ndeci);
778 }
779 o.rec.d = val;
780 o.type = DOUBLE;
781 return o;
782 }
783 obj
vb_SERIESSUM(int narg,obj * arg)784 vb_SERIESSUM (int narg, obj * arg)
785 {
786 obj o;
787
788 ABVInform ("SERIESSUM not yet implemented");
789 o.type = DOUBLE;
790 return o;
791 }
792 obj
vb_SIGN(int narg,obj * arg)793 vb_SIGN (int narg, obj * arg)
794 {
795 obj o;
796 double val = obj2double (arg[0]);
797 if (val > 0)
798 o.rec.d = 1;
799 else if (val < 0)
800 o.rec.d = -1;
801 else
802 o.rec.d = 0;
803 o.type = DOUBLE;
804 return o;
805 }
806 obj
vb_SIN(int narg,obj * arg)807 vb_SIN (int narg, obj * arg)
808 {
809 obj o;
810 o.rec.d = sin (obj2double (arg[0]));
811 o.type = DOUBLE;
812 return o;
813 }
814 obj
vb_SINH(int narg,obj * arg)815 vb_SINH (int narg, obj * arg)
816 {
817 obj o;
818 o.rec.d = sinh (obj2double (arg[0]));
819 o.type = DOUBLE;
820 return o;
821 }
822 obj
vb_SQRT(int narg,obj * arg)823 vb_SQRT (int narg, obj * arg)
824 {
825 obj o;
826 o.rec.d = sqrt (obj2double (arg[0]));
827 o.type = DOUBLE;
828 return o;
829 }
830 obj
vb_SQRTPI(int narg,obj * arg)831 vb_SQRTPI (int narg, obj * arg)
832 {
833 obj o;
834 o.rec.d = sqrt (PI * obj2double (arg[0]));
835 o.type = DOUBLE;
836 return o;
837 }
838
839 obj
vb_SUM(int narg,obj * arg)840 vb_SUM (int narg, obj * arg)
841 {
842 obj o;
843 int r, c;
844 tmpRange *ran;
845 double val = 0;
846 int i;
847
848 for (i = 0; i < narg; i++)
849 {
850 if (arg[i].type == RANGE)
851 {
852 ran = (tmpRange *) arg[i].rec.s;
853 if (ran->wks == NULL)
854 {
855 for (r = ran->r1; r <= ran->r2; r++)
856 for (c = ran->c1; c <= ran->c2; c++)
857 val += get_value (r, c);
858 }
859 else
860 {
861 for (r = ran->r1; r <= ran->r2; r++)
862 for (c = ran->c1; c <= ran->c2; c++)
863 val += get_value_wks (ran->wks, r, c);
864 }
865 }
866 else
867 val += obj2double (arg[i]);
868 }
869 o.rec.d = val;
870 o.type = DOUBLE;
871 return o;
872 }
873
874 obj
vb_SUMIF(int narg,obj * arg)875 vb_SUMIF (int narg, obj * arg)
876 {
877 obj o;
878 obj tmp;
879 int i, r, c;
880 double ret = 0;
881 tmpRange *ran;
882 o.type = DOUBLE;
883 o.rec.d = 0;
884 if (narg < 2)
885 return o;
886 if (arg[0].type != STRING_CONSTANT && arg[0].type != STRING)
887 return o;
888 if (arg[0].rec.s == NULL)
889 return o;
890
891 for (i = 1; i < narg; i++)
892 {
893 if (arg[i].type == RANGE)
894 {
895 ran = (tmpRange *) arg[i].rec.s;
896 if (ran->wks == NULL)
897 {
898 for (r = ran->r1; r <= ran->r2; r++)
899 for (c = ran->c1; c <= ran->c2; c++)
900 {
901 tmp = get_ovalue (r, c);
902 if (makeif (tmp, arg[0].rec.s))
903 ret += obj2double (tmp);
904 }
905 }
906 else
907 {
908 for (r = ran->r1; r <= ran->r2; r++)
909 for (c = ran->c1; c <= ran->c2; c++)
910 {
911 tmp = get_ovalue_wks (ran->wks, r, c);
912 if (makeif (tmp, arg[0].rec.s))
913 ret += obj2double (tmp);
914 }
915 }
916 }
917 else
918 {
919 tmp = id2val (arg[i]);
920 if (makeif (tmp, arg[0].rec.s))
921 ret += obj2double (tmp);
922 }
923 }
924
925 o.rec.d = ret;
926 return o;
927 }
928
929 obj
vb_SUMPRODUCT(int narg,obj * arg)930 vb_SUMPRODUCT (int narg, obj * arg)
931 {
932 obj o;
933
934 ABVInform ("SUMPRODUCT not yet implemented");
935 o.type = DOUBLE;
936 return o;
937 }
938 obj
vb_SUMSQ(int narg,obj * arg)939 vb_SUMSQ (int narg, obj * arg)
940 {
941 obj o;
942 int r, c;
943 tmpRange *ran;
944 double val = 0;
945 int i;
946 double tmp;
947 for (i = 0; i < narg; i++)
948 {
949 if (arg[i].type == RANGE)
950 {
951 ran = (tmpRange *) arg[i].rec.s;
952 if (ran->wks == NULL)
953 {
954 for (r = ran->r1; r <= ran->r2; r++)
955 for (c = ran->c1; c <= ran->c2; c++)
956 {
957 tmp = get_value (r, c);
958 val += tmp * tmp;
959 }
960 }
961 else
962 {
963 for (r = ran->r1; r <= ran->r2; r++)
964 for (c = ran->c1; c <= ran->c2; c++)
965 {
966 tmp = get_value_wks (ran->wks, r, c);
967 val += tmp * tmp;
968 }
969 }
970 }
971 else
972 {
973 tmp = obj2double (arg[i]);
974 val += tmp * tmp;
975 }
976 }
977 o.rec.d = val;
978 o.type = DOUBLE;
979 return o;
980
981 }
982 obj
vb_SUMX2MY2(int narg,obj * arg)983 vb_SUMX2MY2 (int narg, obj * arg)
984 {
985 obj o;
986
987 ABVInform ("SUMX2MY2 not yet implemented");
988 o.type = DOUBLE;
989 return o;
990 }
991 obj
vb_SUMX2PY2(int narg,obj * arg)992 vb_SUMX2PY2 (int narg, obj * arg)
993 {
994 obj o;
995
996 ABVInform ("SUMX2PY2 not yet implemented");
997 o.type = DOUBLE;
998 return o;
999 }
1000 obj
vb_SUMXMY2(int narg,obj * arg)1001 vb_SUMXMY2 (int narg, obj * arg)
1002 {
1003 obj o;
1004
1005 ABVInform ("SUMXMY2 not yet implemented");
1006 o.type = DOUBLE;
1007 return o;
1008 }
1009 obj
vb_TAN(int narg,obj * arg)1010 vb_TAN (int narg, obj * arg)
1011 {
1012 obj o;
1013 o.rec.d = tan (obj2double (arg[0]));
1014 o.type = DOUBLE;
1015 return o;
1016 }
1017 obj
vb_TANH(int narg,obj * arg)1018 vb_TANH (int narg, obj * arg)
1019 {
1020 obj o;
1021 o.rec.d = tanh (obj2double (arg[0]));
1022 o.type = DOUBLE;
1023 return o;
1024 }
1025 obj
vb_TRUNC(int narg,obj * arg)1026 vb_TRUNC (int narg, obj * arg)
1027 {
1028 obj o;
1029 double val = obj2double (arg[0]);
1030 double ndeci = 0;
1031 int valint;
1032 if (narg > 1)
1033 ndeci = obj2double (arg[1]);
1034
1035 if (ndeci >= 0)
1036 {
1037 valint = val * pow (10, ndeci);
1038 val = valint * pow (10, -ndeci);
1039 }
1040 o.rec.d = val;
1041
1042 o.type = DOUBLE;
1043 return o;
1044 }
1045