functions.c 62 KB
Newer Older
Arturo Espinosa's avatar
Arturo Espinosa committed
1
/*
2
 * fn-math.c:  Built in mathematical functions and functions registration
Arturo Espinosa's avatar
Arturo Espinosa committed
3
 *
Jukka-Pekka Iivonen's avatar
Jukka-Pekka Iivonen committed
4
 * Authors:
Arturo Espinosa's avatar
Arturo Espinosa committed
5
 *  Miguel de Icaza (miguel@gnu.org)
Jukka-Pekka Iivonen's avatar
Jukka-Pekka Iivonen committed
6
 *  Jukka-Pekka Iivonen (iivonen@iki.fi)
Arturo Espinosa's avatar
Arturo Espinosa committed
7
8
 */
#include <config.h>
Morten Welinder's avatar
Morten Welinder committed
9
#include <math.h>
Arturo Espinosa's avatar
Arturo Espinosa committed
10
11
12
13
#include "gnumeric.h"
#include "utils.h"
#include "func.h"

Donnie Barnes's avatar
Donnie Barnes committed
14
15
16
#if 0
/* help template */
static char *help_ = {
17
18
	N_("@FUNCTION=NAME\n"
	   "@SYNTAX=(b1, b2, ...)\n"
Donnie Barnes's avatar
Donnie Barnes committed
19

20
	   "@DESCRIPTION"
Donnie Barnes's avatar
Donnie Barnes committed
21
	   ""
22
	   "\n"
Donnie Barnes's avatar
Donnie Barnes committed
23
24
25

	   ""
	   ""
26
	   "\n"
Morten Welinder's avatar
Morten Welinder committed
27

Donnie Barnes's avatar
Donnie Barnes committed
28
29
30
	   ""
	   ""
	   ""
31
32
	   ""
	   "@SEEALSO=")
Donnie Barnes's avatar
Donnie Barnes committed
33
34
35
36
};

#endif

Jukka-Pekka Iivonen's avatar
Jukka-Pekka Iivonen committed
37
static int
Morten Welinder's avatar
Morten Welinder committed
38
gcd (int a, int b)
Jukka-Pekka Iivonen's avatar
Jukka-Pekka Iivonen committed
39
{
Morten Welinder's avatar
Morten Welinder committed
40
	/* Euclid's Algorithm.	Assumes non-negative numbers.  */
Morten Welinder's avatar
Morten Welinder committed
41

Morten Welinder's avatar
Morten Welinder committed
42
43
	while (b != 0) {
		int r;
Morten Welinder's avatar
Morten Welinder committed
44

Morten Welinder's avatar
Morten Welinder committed
45
46
47
48
		r = a - (a / b) * b;	/* r = remainder from
					 * dividing a by b	*/
		a = b;
		b = r;
Jukka-Pekka Iivonen's avatar
Jukka-Pekka Iivonen committed
49
	}
Morten Welinder's avatar
Morten Welinder committed
50
	return a;
Jukka-Pekka Iivonen's avatar
Jukka-Pekka Iivonen committed
51
}
Morten Welinder's avatar
Morten Welinder committed
52

53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
static float_t
pow10 (int n)
{
	float_t res = 1.0;
	float_t p;
	const int maxn = 300;

	if (n >= 0) {
		p = 10.0;
		n = (n > maxn) ? maxn : n;
	} else {
		p = 0.1;
		/* Note carefully that we avoid overflow.  */
		n = (n < -maxn) ? maxn : -n;
	}
	while (n > 0) {
		if (n & 1) res *= p;
		p *= p;
		n >>= 1;
	}
	return res;
}

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
129
130

typedef struct {
        GSList *list;
        int    num;
} math_sums_t;

static int
callback_function_sumxy (Sheet *sheet, int col, int row,
			 Cell *cell, void *user_data)
{
        math_sums_t *mm = user_data;
        float_t     x;
	gpointer    p;

	if (cell == NULL || cell->value == NULL)
	        return TRUE;

        switch (cell->value->type) {
	case VALUE_INTEGER:
	        x = cell->value->v.v_int;
		break;
	case VALUE_FLOAT:
	        x = cell->value->v.v_float;
		break;
	default:
	        return TRUE;
	}

	p = g_new(float_t, 1);
	*((float_t *) p) = x;
	mm->list = g_slist_append(mm->list, p);
	mm->num++;

	return TRUE;
}

typedef struct {
        GSList              *list;
        criteria_test_fun_t fun;
        Value               *test_value;
        int                 num;
} math_criteria_t;

static int
callback_function_criteria (Sheet *sheet, int col, int row,
			    Cell *cell, void *user_data)
{
        math_criteria_t *mm = user_data;
	Value           *v;

	if (cell == NULL || cell->value == NULL)
	        return TRUE;

        switch (cell->value->type) {
	case VALUE_INTEGER:
Michael Meeks's avatar
Michael Meeks committed
131
	        v = value_new_int (cell->value->v.v_int);
132
133
		break;
	case VALUE_FLOAT:
Michael Meeks's avatar
Michael Meeks committed
134
	        v = value_new_float (cell->value->v.v_float);
135
136
		break;
	case VALUE_STRING:
Michael Meeks's avatar
Michael Meeks committed
137
	        v = value_new_string (cell->value->v.str->str);
138
139
140
141
142
143
		break;
	default:
	        return TRUE;
	}

	if (mm->fun(v, mm->test_value)) {
Morten Welinder's avatar
Morten Welinder committed
144
		mm->list = g_slist_append (mm->list, v);
145
146
147
148
149
150
151
		mm->num++;
	} else
	        value_release(v);

	return TRUE;
}

Jukka-Pekka Iivonen's avatar
Jukka-Pekka Iivonen committed
152
153
154
155
156
static char *help_gcd = {
	N_("@FUNCTION=GCD\n"
	   "@SYNTAX=GCD(a,b)\n"

	   "@DESCRIPTION="
Jukka-Pekka Iivonen's avatar
Jukka-Pekka Iivonen committed
157
	   "GCD returns the greatest common divisor of two numbers. "
Jukka-Pekka Iivonen's avatar
Jukka-Pekka Iivonen committed
158
159
160
161
162
163
164
165
166
167
168
169
170
	   "\n"
	   "If any of the arguments is less than zero, GCD returns #NUM! "
	   "error. "
	   "\n"
	   "@SEEALSO=LCM")
};

static Value *
gnumeric_gcd (struct FunctionDefinition *i,
	      Value *argv [], char **error_string)
{
        float_t a, b;

Michael Meeks's avatar
Michael Meeks committed
171
172
	a = value_get_as_float (argv[0]);
	b = value_get_as_float (argv[1]);
Jukka-Pekka Iivonen's avatar
Jukka-Pekka Iivonen committed
173
174

        if (a < 0 || b < 0) {
Morten Welinder's avatar
Morten Welinder committed
175
		*error_string = gnumeric_err_NUM;
Jukka-Pekka Iivonen's avatar
Jukka-Pekka Iivonen committed
176
177
		return NULL;
	}
Morten Welinder's avatar
Morten Welinder committed
178

Michael Meeks's avatar
Michael Meeks committed
179
	return value_new_int (gcd(a, b));
Jukka-Pekka Iivonen's avatar
Jukka-Pekka Iivonen committed
180
181
}

Jukka-Pekka Iivonen's avatar
Jukka-Pekka Iivonen committed
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
static char *help_lcm = {
	N_("@FUNCTION=LCM\n"
	   "@SYNTAX=LCM(number1,number2,...)\n"

	   "@DESCRIPTION="
	   "LCM returns the least common multiple of integers.  The least "
	   "common multiple is the smallest positive number that is a "
	   "multiple of all integer arguments given. "
	   "\n"
	   "If any of the arguments is less than one, LCM returns #NUM! "
	   "error. "
	   "\n"
	   "@SEEALSO=GCD")
};

static int
callback_function_lcm (Sheet *sheet, Value *value,
		       char **error_string, void *closure)
{
	Value *result = closure;

	switch (value->type){
	case VALUE_INTEGER:
	        if (value->v.v_int < 1)
		        return FALSE;
	        result->v.v_int /= gcd(result->v.v_int, value->v.v_int);
		result->v.v_int *= value->v.v_int;
		break;
	default:
	        return FALSE;
	}
Morten Welinder's avatar
Morten Welinder committed
213

Jukka-Pekka Iivonen's avatar
Jukka-Pekka Iivonen committed
214
215
216
217
	return TRUE;
}

static Value *
Morten Welinder's avatar
Morten Welinder committed
218
gnumeric_lcm (Sheet *sheet, GList *expr_node_list,
Jukka-Pekka Iivonen's avatar
Jukka-Pekka Iivonen committed
219
220
221
222
223
224
225
226
227
228
	      int eval_col, int eval_row, char **error_string)
{
	Value *result;

	result = g_new (Value, 1);
	result->type = VALUE_INTEGER;
	result->v.v_int = 1;

	if (function_iterate_argument_values (sheet, callback_function_lcm,
					      result, expr_node_list,
Morten Welinder's avatar
Morten Welinder committed
229
					      eval_col, eval_row,
Jukka-Pekka Iivonen's avatar
Jukka-Pekka Iivonen committed
230
					      error_string) == FALSE) {
Morten Welinder's avatar
Morten Welinder committed
231
		*error_string = gnumeric_err_NUM;
Jukka-Pekka Iivonen's avatar
Jukka-Pekka Iivonen committed
232
233
234
235
236
237
		return NULL;
	}

	return result;
}

238
239
240
static char *help_abs = {
	N_("@FUNCTION=ABS\n"
	   "@SYNTAX=ABS(b1)\n"
241

242
243
244
	   "@DESCRIPTION=Implements the Absolute Value function:  the result is "
	   "to drop the negative sign (if present).  This can be done for "
	   "integers and floating point numbers."
245
	   "\n"
246
	   "Performing this function on a string or empty cell simply does nothing."
247
	   "\n"
248
	   "@SEEALSO=CEIL, FLOOR")
249
250
};

251
static Value *
252
253
gnumeric_abs (struct FunctionDefinition *i,
	      Value *argv [], char **error_string)
254
{
Michael Meeks's avatar
Michael Meeks committed
255
	return value_new_float (fabs (value_get_as_float (argv [0])));
256
}
257
258

static char *help_acos = {
259
	N_("@FUNCTION=ACOS\n"
260
	   "@SYNTAX=ACOS(x)\n"
261

262
	   "@DESCRIPTION="
263
264
	   "The ACOS function calculates the arc cosine of x; that "
	   " is the value whose cosine is x.  If x  falls  outside  the "
265
266
	   " range -1 to 1, ACOS fails and returns the error 'acos - domain error'. "
	   " The value it returns is in radians. "
267
	   "\n"
268
269
	   "Performing this function on a string or empty cell simply does nothing. "
	   "This function only takes one argument."
270
271
	   "\n"
	   "@SEEALSO=COS, SIN, DEGREES, RADIANS")
272
273
};

274
static Value *
275
276
gnumeric_acos (struct FunctionDefinition *i,
	       Value *argv [], char **error_string)
277
278
{
	float_t t;
Donnie Barnes's avatar
Donnie Barnes committed
279

Michael Meeks's avatar
Michael Meeks committed
280
	t = value_get_as_float (argv [0]);
281
282
283
284
	if ((t < -1.0) || (t > 1.0)){
		*error_string = _("acos - domain error");
		return NULL;
	}
Michael Meeks's avatar
Michael Meeks committed
285
	return value_new_float (acos (t));
286
287
288
289
}

static char *help_acosh = {
	N_("@FUNCTION=ACOSH\n"
290
	   "@SYNTAX=ACOSH(x)\n"
291
292
293

	   "@DESCRIPTION="
	   "The ACOSH  function  calculates  the inverse hyperbolic "
294
295
	   "cosine of x; that is the value whose hyperbolic cosine is "
	   "x. If x is less than 1.0, acosh() returns the error "
296
	   " 'acosh - domain error'"
Arturo Espinosa's avatar
Arturo Espinosa committed
297
	   "\n"
298
299
	   "Performing this function on a string or empty cell simply does nothing. "
	   "This function only takes one argument."
300
	   "\n"
301
	   "@SEEALSO=ACOS, DEGREES, RADIANS ")
Donnie Barnes's avatar
Donnie Barnes committed
302
303
};

304
static Value *
305
306
gnumeric_acosh (struct FunctionDefinition *i,
		Value *argv [], char **error_string)
307
308
309
{
	float_t t;

Michael Meeks's avatar
Michael Meeks committed
310
	t = value_get_as_float (argv [0]);
311
312
313
314
	if (t < 1.0){
		*error_string = _("acosh - domain error");
		return NULL;
	}
Michael Meeks's avatar
Michael Meeks committed
315
	return value_new_float (acosh (t));
316
317
318
319
}

static char *help_asin = {
	N_("@FUNCTION=ASIN\n"
320
	   "@SYNTAX=ASIN(x)\n"
321
322

	   "@DESCRIPTION="
323
324
	   "The ASIN function calculates the arc sine of x; that is "
	   "the value whose sine is x. If x falls outside  the  range "
325
326
327
328
329
330
331
332
	   "-1 to 1, ASIN fails and returns the error 'asin - domain error'   "
	   "\n"
	   "Performing this function on a string or empty cell simply does nothing. "
	   "This function only takes one argument."
	   "\n"
	   "@SEEALSO=SIN, COS, ASINH, DEGREES, RADIANS")
};

Arturo Espinosa's avatar
Arturo Espinosa committed
333
static Value *
334
335
gnumeric_asin (struct FunctionDefinition *i,
	       Value *argv [], char **error_string)
Arturo Espinosa's avatar
Arturo Espinosa committed
336
337
338
{
	float_t t;

Michael Meeks's avatar
Michael Meeks committed
339
	t = value_get_as_float (argv [0]);
Arturo Espinosa's avatar
Arturo Espinosa committed
340
341
342
343
	if ((t < -1.0) || (t > 1.0)){
		*error_string = _("asin - domain error");
		return NULL;
	}
Michael Meeks's avatar
Michael Meeks committed
344
	return value_new_float (asin (t));
Arturo Espinosa's avatar
Arturo Espinosa committed
345
346
}

347
348
static char *help_asinh = {
	N_("@FUNCTION=ASINH\n"
349
	   "@SYNTAX=ASINH(x)\n"
350
351

	   "@DESCRIPTION="
352
353
	   "The ASINH  function  calculates  the inverse hyperbolic "
	   " sine of x; that is the value whose hyperbolic sine is x. "
354
355
356
357
358
359
360
361
	   "\n"

	   "Performing this function on a string or empty cell simply does nothing. "
	   "This function only takes one argument."
	   "\n"
	   "@SEEALSO=ASIN, SIN, COS, DEGREES, RADIANS")
};

Arturo Espinosa's avatar
Arturo Espinosa committed
362
static Value *
363
364
gnumeric_asinh (struct FunctionDefinition *i,
		Value *argv [], char **error_string)
Arturo Espinosa's avatar
Arturo Espinosa committed
365
{
Michael Meeks's avatar
Michael Meeks committed
366
	return value_new_float (asinh (value_get_as_float (argv [0])));
367
}
Arturo Espinosa's avatar
Arturo Espinosa committed
368

369
370
static char *help_atan = {
	N_("@FUNCTION=ATAN\n"
371
	   "@SYNTAX=ATAN(x)\n"
Arturo Espinosa's avatar
Arturo Espinosa committed
372

373
	   "@DESCRIPTION="
374
375
	   "The ATAN function calculates the arc tangent of x; that "
	   " is the value whose tangent is x."
376
377
378
379
380
381
382
383
384
	   "Return value is in radians."
	   "\n"

	   "Performing this function on a string or empty cell simply does nothing. "
	   "This function only takes one argument."
	   "\n"

	   "@SEEALSO=TAN, COS, SIN, DEGREES, RADIANS")
};
Arturo Espinosa's avatar
Arturo Espinosa committed
385
386

static Value *
387
388
gnumeric_atan (struct FunctionDefinition *i,
	       Value *argv [], char **error_string)
Arturo Espinosa's avatar
Arturo Espinosa committed
389
{
Michael Meeks's avatar
Michael Meeks committed
390
	return value_new_float (atan (value_get_as_float (argv [0])));
Arturo Espinosa's avatar
Arturo Espinosa committed
391
392
}

393
394
static char *help_atanh = {
	N_("@FUNCTION=ATANH\n"
395
	   "@SYNTAX=ATANH(x)\n"
396
397
398

	   "@DESCRIPTION="
	   "The  ATANH  function  calculates  the inverse hyperbolic "
399
400
	   "tangent of x; that is the value whose  hyperbolic  tangent "
	   "is  x.   If  the  absolute value of x is greater than 1.0, "
401
402
403
404
405
406
407
408
409
	   " ATANH returns an error of 'atanh: domain error'      "
	   "\n"

	   "Performing this function on a string or empty cell simply does nothing. "
	   "This function only takes one argument."
	   "\n"
	   "@SEEALSO=ATAN, TAN, SIN, COS, DEGREES, RADIANS")
};

Arturo Espinosa's avatar
Arturo Espinosa committed
410
static Value *
411
412
gnumeric_atanh (struct FunctionDefinition *i,
		Value *argv [], char **error_string)
Arturo Espinosa's avatar
Arturo Espinosa committed
413
414
415
{
	float_t t;

Michael Meeks's avatar
Michael Meeks committed
416
	t = value_get_as_float (argv [0]);
Arturo Espinosa's avatar
Arturo Espinosa committed
417
418
419
420
	if ((t <= -1.0) || (t >= 1.0)){
		*error_string = _("atanh: domain error");
		return NULL;
	}
Michael Meeks's avatar
Michael Meeks committed
421
	return value_new_float (atanh (value_get_as_float (argv [0])));
Arturo Espinosa's avatar
Arturo Espinosa committed
422
423
}

424
static char *help_atan2 = {
425
	N_("@FUNCTION=ATAN2\n"
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
	   "@SYNTAX=ATAN2(b1,b2)\n"

	   "@DESCRIPTION="
	   "The ATAN2 function calculates the arc tangent of the two "
	   "variables b1 and b2.  It is similar to calculating  the  arc "
	   "tangent  of b2 / b1, except that the signs of both arguments "
	   "are used to determine the quadrant of the result. "
	   "The result is in Radians."
	   "\n"

	   "Performing this function on a string or empty cell simply does nothing. "
	   "\n"
	   "@SEEALSO=ATAN, ATANH, COS, SIN, DEGREES, RADIANS")
};

Arturo Espinosa's avatar
Arturo Espinosa committed
441
static Value *
442
443
gnumeric_atan2 (struct FunctionDefinition *i,
		Value *argv [], char **error_string)
Arturo Espinosa's avatar
Arturo Espinosa committed
444
{
Morten Welinder's avatar
Morten Welinder committed
445
446
	return value_new_float (atan2 (value_get_as_float (argv [1]),
				       value_get_as_float (argv [0])));
Arturo Espinosa's avatar
Arturo Espinosa committed
447
448
}

449
450
static char *help_ceil = {
	N_("@FUNCTION=CEIL\n"
451
	   "@SYNTAX=CEIL(x)\n"
452

453
454
	   "@DESCRIPTION=The CEIL function rounds x up to the next nearest "
	   "integer.\n"
455
456
457

	   "Performing this function on a string or empty cell simply does nothing."
	   "\n"
Morten Welinder's avatar
Morten Welinder committed
458

459
460
461
	   "@SEEALSO=ABS, FLOOR, INT")
};

Arturo Espinosa's avatar
Arturo Espinosa committed
462
static Value *
463
464
gnumeric_ceil (struct FunctionDefinition *i,
	       Value *argv [], char **error_string)
Arturo Espinosa's avatar
Arturo Espinosa committed
465
{
Michael Meeks's avatar
Michael Meeks committed
466
	return value_new_float (ceil (value_get_as_float (argv [0])));
467
468
}

469
470
471
472
473
474
475
476
477
static char *help_countif = {
	N_("@FUNCTION=COUNTIF\n"
	   "@SYNTAX=COUNTIF(range,criteria)\n"

	   "@DESCRIPTION="
	   "COUNTIF function counts the number of cells in the given range "
	   "that meet the given criteria. "

	   "\n"
Morten Welinder's avatar
Morten Welinder committed
478

479
480
481
482
483
484
485
486
	   "@SEEALSO=COUNT,SUMIF")
};

static Value *
gnumeric_countif (struct FunctionDefinition *i,
		  Value *argv [], char **error_string)
{
        Value           *range = argv[0];
Morten Welinder's avatar
Morten Welinder committed
487
	Value           *tmpvalue = NULL;
488
489
490
491
492
493
494
495
496
	math_criteria_t items;
	int             ret;
	GSList          *list;

	items.num  = 0;
	items.list = NULL;

	if ((!VALUE_IS_NUMBER(argv[1]) && argv[1]->type != VALUE_STRING)
	    || (range->type != VALUE_CELLRANGE)) {
Morten Welinder's avatar
Morten Welinder committed
497
		*error_string = gnumeric_err_VALUE;
498
499
500
501
502
503
		return NULL;
	}

	if (VALUE_IS_NUMBER(argv[1])) {
	        items.fun = (criteria_test_fun_t) criteria_test_equal;
		items.test_value = argv[1];
Morten Welinder's avatar
Morten Welinder committed
504
	} else {
505
506
	        parse_criteria(argv[1]->v.str->str,
			       &items.fun, &items.test_value);
Morten Welinder's avatar
Morten Welinder committed
507
508
		tmpvalue = items.test_value;
	}
509
510
511

	ret = sheet_cell_foreach_range (
	  range->v.cell_range.cell_a.sheet, TRUE,
Morten Welinder's avatar
Morten Welinder committed
512
	  range->v.cell_range.cell_a.col,
513
514
515
516
517
	  range->v.cell_range.cell_a.row,
	  range->v.cell_range.cell_b.col,
	  range->v.cell_range.cell_b.row,
	  callback_function_criteria,
	  &items);
Morten Welinder's avatar
Morten Welinder committed
518
519
520
521

	if (tmpvalue)
		value_release (tmpvalue);

522
	if (ret == FALSE) {
Morten Welinder's avatar
Morten Welinder committed
523
		*error_string = gnumeric_err_VALUE;
524
525
526
527
528
529
		return NULL;
	}

        list = items.list;

	while (list != NULL) {
Morten Welinder's avatar
Morten Welinder committed
530
		value_release (list->data);
531
532
533
534
		list = list->next;
	}
	g_slist_free(items.list);

Michael Meeks's avatar
Michael Meeks committed
535
	return value_new_int (items.num);
536
537
538
539
540
541
542
543
544
545
546
}

static char *help_sumif = {
	N_("@FUNCTION=SUMIF\n"
	   "@SYNTAX=SUMIF(range,criteria)\n"

	   "@DESCRIPTION="
	   "SUMIF function sums the values in the given range that meet "
	   "the given criteria. "

	   "\n"
Morten Welinder's avatar
Morten Welinder committed
547

548
549
550
551
552
553
554
555
	   "@SEEALSO=COUNTIF,SUM")
};

static Value *
gnumeric_sumif (struct FunctionDefinition *i,
		Value *argv [], char **error_string)
{
        Value           *range = argv[0];
Morten Welinder's avatar
Morten Welinder committed
556
	Value           *tmpvalue = NULL;
557
558
559
560
561
562
563
564
565
566
	math_criteria_t items;
	int             ret;
	float_t         sum;
	GSList          *list;

	items.num  = 0;
	items.list = NULL;

	if ((!VALUE_IS_NUMBER(argv[1]) && argv[1]->type != VALUE_STRING)
	    || (range->type != VALUE_CELLRANGE)) {
Morten Welinder's avatar
Morten Welinder committed
567
		*error_string = gnumeric_err_VALUE;
568
569
570
571
572
573
		return NULL;
	}

	if (VALUE_IS_NUMBER(argv[1])) {
	        items.fun = (criteria_test_fun_t) criteria_test_equal;
		items.test_value = argv[1];
Morten Welinder's avatar
Morten Welinder committed
574
	} else {
575
576
	        parse_criteria(argv[1]->v.str->str,
			       &items.fun, &items.test_value);
Morten Welinder's avatar
Morten Welinder committed
577
578
		tmpvalue = items.test_value;
	}
579
580
581

	ret = sheet_cell_foreach_range (
	  range->v.cell_range.cell_a.sheet, TRUE,
Morten Welinder's avatar
Morten Welinder committed
582
	  range->v.cell_range.cell_a.col,
583
584
585
586
587
	  range->v.cell_range.cell_a.row,
	  range->v.cell_range.cell_b.col,
	  range->v.cell_range.cell_b.row,
	  callback_function_criteria,
	  &items);
Morten Welinder's avatar
Morten Welinder committed
588
589
590
591

	if (tmpvalue)
		value_release (tmpvalue);

592
	if (ret == FALSE) {
Morten Welinder's avatar
Morten Welinder committed
593
		*error_string = gnumeric_err_VALUE;
594
595
596
597
598
599
600
		return NULL;
	}

        list = items.list;
	sum = 0;

	while (list != NULL) {
Morten Welinder's avatar
Morten Welinder committed
601
	        Value *v = list->data;
602
603

		if (v != NULL)
Michael Meeks's avatar
Michael Meeks committed
604
		       sum += value_get_as_float (v);
Morten Welinder's avatar
Morten Welinder committed
605
		value_release (v);
606
607
608
609
		list = list->next;
	}
	g_slist_free(items.list);

Michael Meeks's avatar
Michael Meeks committed
610
	return value_new_float (sum);
611
612
}

613
614
615
616
617
618
619
620
621
622
623
static char *help_ceiling = {
	N_("@FUNCTION=CEILING\n"
	   "@SYNTAX=CEILING(x,significance)\n"

	   "@DESCRIPTION=The CEILING function rounds x up to the nearest "
	   "multiple of significance. "
	   "\n"

	   "If x or significance is non-numeric CEILING returns #VALUE! error. "
	   "If n and significance have different signs CEILING returns #NUM! error. "
	   "\n"
Morten Welinder's avatar
Morten Welinder committed
624

625
626
627
628
	   "@SEEALSO=CEIL")
};

static Value *
629
630
gnumeric_ceiling (struct FunctionDefinition *i,
		  Value *argv [], char **error_string)
631
{
Morten Welinder's avatar
Morten Welinder committed
632
        float_t number, s;
633

Morten Welinder's avatar
Morten Welinder committed
634
635
636
637
638
	number = value_get_as_float (argv[0]);
	if (argv[1] == NULL)
	        s = (number >= 0) ? 1.0 : -1.0;
	else {
	        s = value_get_as_float (argv[1]);
639
	}
Morten Welinder's avatar
Morten Welinder committed
640
641

	if (s == 0 || number / s < 0) {
Morten Welinder's avatar
Morten Welinder committed
642
		*error_string = gnumeric_err_NUM;
Morten Welinder's avatar
Morten Welinder committed
643
		return NULL;
644
645
	}

Morten Welinder's avatar
Morten Welinder committed
646
	return value_new_float (ceil (number / s) * s);
647
648
}

649
650
static char *help_cos = {
	N_("@FUNCTION=COS\n"
651
	   "@SYNTAX=COS(x)\n"
652
653

	   "@DESCRIPTION="
654
	   "The  COS  function  returns  the cosine of x, where x is "
655
656
657
658
659
660
661
662
           "given in radians.  "
	   "\n"
	   "Performing this function on a string or empty cell simply does nothing. "
	   "This function only takes one argument."
	   "\n"
	   "@SEEALSO=COSH, SIN, SINH, TAN, TANH, RADIANS, DEGREES")
};

Arturo Espinosa's avatar
Arturo Espinosa committed
663
static Value *
664
665
gnumeric_cos (struct FunctionDefinition *i,
	      Value *argv [], char **error_string)
Arturo Espinosa's avatar
Arturo Espinosa committed
666
{
Michael Meeks's avatar
Michael Meeks committed
667
	return value_new_float (cos (value_get_as_float (argv [0])));
668
}
Arturo Espinosa's avatar
Arturo Espinosa committed
669

670
671
static char *help_cosh = {
	N_("@FUNCTION=COSH\n"
672
	   "@SYNTAX=COSH(x)\n"
Arturo Espinosa's avatar
Arturo Espinosa committed
673

674
	   "@DESCRIPTION="
675
676
677
	   "The COSH  function  returns the hyperbolic cosine of x, "
	   " which is defined mathematically as (exp(x) + exp(-x)) / 2.   "
	   " x is in radians. "
678
679
680
681
682
683
	   "\n"
	   "Performing this function on a string or empty cell simply does nothing. "
	   "This function only takes one argument."
	   "\n"
	   "@SEEALSO=COS, SIN, SINH, TAN, TANH, RADIANS, DEGREES, EXP")
};
Arturo Espinosa's avatar
Arturo Espinosa committed
684
685

static Value *
686
687
gnumeric_cosh (struct FunctionDefinition *i,
	       Value *argv [], char **error_string)
Arturo Espinosa's avatar
Arturo Espinosa committed
688
{
Michael Meeks's avatar
Michael Meeks committed
689
	return value_new_float (cosh (value_get_as_float (argv [0])));
Arturo Espinosa's avatar
Arturo Espinosa committed
690
691
}

692
693
static char *help_degrees = {
	N_("@FUNCTION=DEGREES\n"
694
	   "@SYNTAX=DEGREES(x)\n"
695
696

	   "@DESCRIPTION="
697
698
	   "Computes the number of degrees equivalent to "
	   " x radians."
699
700
701
702
	   "\n"

	   "Performing this function on a string or empty cell simply does nothing. "
	   "\n"
Morten Welinder's avatar
Morten Welinder committed
703

704
705
706
	   "@SEEALSO=RADIANS, PI")
};

Arturo Espinosa's avatar
Arturo Espinosa committed
707
static Value *
708
709
gnumeric_degrees (struct FunctionDefinition *i,
		  Value *argv [], char **error_string)
Arturo Espinosa's avatar
Arturo Espinosa committed
710
{
Michael Meeks's avatar
Michael Meeks committed
711
	return value_new_float ((value_get_as_float (argv [0]) * 180.0) / M_PI);
712
}
Arturo Espinosa's avatar
Arturo Espinosa committed
713

714
715
static char *help_exp = {
	N_("@FUNCTION=EXP\n"
716
	   "@SYNTAX=EXP(x)\n"
Arturo Espinosa's avatar
Arturo Espinosa committed
717

718
719
	   "@DESCRIPTION="
	   "Computes the value of e(the base of natural logarithmns) raised "
720
	   "to the power of x. "
721
722
723
724
725
	   "\n"
	   "Performing this function on a string or empty cell returns an error."
	   "\n"
	   "@SEEALSO=LOG, LOG2, LOG10")
};
Arturo Espinosa's avatar
Arturo Espinosa committed
726
727

static Value *
728
729
gnumeric_exp (struct FunctionDefinition *i,
	      Value *argv [], char **error_string)
Arturo Espinosa's avatar
Arturo Espinosa committed
730
{
Michael Meeks's avatar
Michael Meeks committed
731
	return value_new_float (exp (value_get_as_float (argv [0])));
Arturo Espinosa's avatar
Arturo Espinosa committed
732
733
}

734
float_t
735
736
737
738
739
740
741
fact (int n)
{
	if (n == 0)
		return 1;
	return (n * fact (n - 1));
}

742
743
static char *help_fact = {
	N_("@FUNCTION=FACT\n"
744
	   "@SYNTAX=FACT(x)\n"
745
746

	   "@DESCRIPTION="
747
	   "Computes the factorial of x. ie, x!"
748
749
750
751
752
753
754
	   "\n"
	   "Performing this function on a string or empty cell returns an error"
	   "\n"
	   "\n"
	   "@SEEALSO=")
};

755
static Value *
756
757
gnumeric_fact (struct FunctionDefinition *id,
	       Value *argv [], char **error_string)
758
{
Morten Welinder's avatar
Morten Welinder committed
759
760
	float_t x;
	gboolean x_is_integer;
761

Morten Welinder's avatar
Morten Welinder committed
762
	if (!VALUE_IS_NUMBER (argv[0])) {
Morten Welinder's avatar
Morten Welinder committed
763
		*error_string = gnumeric_err_NUM;
764
765
766
		return NULL;
	}

Morten Welinder's avatar
Morten Welinder committed
767
768
	x = value_get_as_float (argv[0]);
	if (x < 0){
Morten Welinder's avatar
Morten Welinder committed
769
		*error_string = gnumeric_err_NUM;
770
771
		return NULL;
	}
Morten Welinder's avatar
Morten Welinder committed
772
	x_is_integer = (x == floor (x));
Morten Welinder's avatar
Morten Welinder committed
773

Morten Welinder's avatar
Morten Welinder committed
774
775
776
777
778
779
780
	if (x > 12 || !x_is_integer) {
		float_t res = exp (lgamma (x + 1));
		if (x_is_integer)
			res = floor (res + 0.5);  /* Round, just in case.  */
		return value_new_float (res);
	} else
		return value_new_int (fact (x));
781
782
}

Jukka-Pekka Iivonen's avatar
Jukka-Pekka Iivonen committed
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
static char *help_combin = {
	N_("@FUNCTION=COMBIN\n"
	   "@SYNTAX=COMBIN(n,k)\n"

	   "@DESCRIPTION="
	   "Computes the number of combinations."
	   "\n"
	   "Performing this function on a non-integer or a negative number "
           "returns an error. Also if n is less than k returns an error."
	   "\n"
	   "\n"
	   "@SEEALSO=")
};

float_t
combin (int n, int k)
{
800
801
802
803
804
805
806
807
808
809
810
	if (n >= 15) {
		float_t res;

		res = exp (lgamma (n + 1) - lgamma (k + 1) - lgamma (n - k + 1));
		return floor (res + 0.5);  /* Round, just in case.  */
	} else {
		float_t res;

		res = fact (n) / fact (k) / fact (n - k);
		return res;
	}
Jukka-Pekka Iivonen's avatar
Jukka-Pekka Iivonen committed
811
812
813
}

static Value *
814
815
gnumeric_combin (struct FunctionDefinition *id,
		 Value *argv [], char **error_string)
Jukka-Pekka Iivonen's avatar
Jukka-Pekka Iivonen committed
816
{
817
	int n ,k;
Jukka-Pekka Iivonen's avatar
Jukka-Pekka Iivonen committed
818

819
820
821
822
	n = value_get_as_int (argv[0]);
	k = value_get_as_int (argv[1]);

	if (k >= 0 && n >= k)
Michael Meeks's avatar
Michael Meeks committed
823
		return value_new_float (combin (n ,k));
824

Morten Welinder's avatar
Morten Welinder committed
825
	*error_string = gnumeric_err_NUM;
826
	return NULL;
Jukka-Pekka Iivonen's avatar
Jukka-Pekka Iivonen committed
827
828
}

829
830
static char *help_floor = {
	N_("@FUNCTION=FLOOR\n"
Morten Welinder's avatar
Morten Welinder committed
831
	   "@SYNTAX=FLOOR(x,significance)\n"
832

833
	   "@DESCRIPTION=The FLOOR function rounds x down to the next nearest "
Morten Welinder's avatar
Morten Welinder committed
834
	   "multiple of @significance.  @significance defaults to 1."
835
836
837
838
839
840
	   "\n"
	   "Performing this function on a string or empty cell simply does nothing."
	   "\n"
	   "@SEEALSO=CEIL, ABS, INT")
};

Arturo Espinosa's avatar
Arturo Espinosa committed
841
static Value *
842
843
gnumeric_floor (struct FunctionDefinition *i,
		Value *argv [], char **error_string)
Arturo Espinosa's avatar
Arturo Espinosa committed
844
{
Morten Welinder's avatar
Morten Welinder committed
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
        float_t number, s;

	number = value_get_as_float (argv[0]);
	if (argv[1] == NULL)
	        s = (number >= 0) ? 1.0 : -1.0;
	else {
	        s = value_get_as_float (argv[1]);
	}

	if (s == 0 || number / s < 0) {
		*error_string = gnumeric_err_NUM;
		return NULL;
	}

	return value_new_float (floor (number / s) * s);
860
}
Arturo Espinosa's avatar
Arturo Espinosa committed
861

862
863
864
static char *help_int = {
	N_("@FUNCTION=INT\n"
	   "@SYNTAX=INT(b1, b2, ...)\n"
Arturo Espinosa's avatar
Arturo Espinosa committed
865

866
867
868
	   "@DESCRIPTION="
	   "The INT function round b1 now to the nearest int. "
	   "Where 'nearest' implies being closer to zero. "
Morten Welinder's avatar
Morten Welinder committed
869
	   "Equivalent to FLOOR(b1) for b1 >= 0, amd CEIL(b1) "
Morten Welinder's avatar
Morten Welinder committed
870
	   "for b1 < 0. "
871
872
873
874
875
876
	   "\n"
	   "Performing this function on a string or empty cell simply does nothing."
	   ""
	   "\n"
	   "@SEEALSO=FLOOR, CEIL, ABS")
};
Arturo Espinosa's avatar
Arturo Espinosa committed
877
878

static Value *
879
880
gnumeric_int (struct FunctionDefinition *i,
	      Value *argv [], char **error_string)
Arturo Espinosa's avatar
Arturo Espinosa committed
881
882
883
{
	float_t t;

Morten Welinder's avatar
Morten Welinder committed
884
885
	/* FIXME: What about strings and empty cells?  */

Michael Meeks's avatar
Michael Meeks committed
886
	t = value_get_as_float (argv [0]);
Morten Welinder's avatar
Morten Welinder committed
887

Michael Meeks's avatar
Michael Meeks committed
888
	return value_new_float (t > 0.0 ? floor (t) : ceil (t));
Arturo Espinosa's avatar
Arturo Espinosa committed
889
890
}

891
892
static char *help_log = {
	N_("@FUNCTION=LOG\n"
893
	   "@SYNTAX=LOG(x[,base])\n"
894
895

	   "@DESCRIPTION="
896
897
	   "Computes the logarithm of x in the given base.  If no base is "
	   "given LOG returns the logarithm in base 10. "
898
	   "\n"
899
	   "@SEEALSO=LN, LOG2, LOG10")
900
901
};

Arturo Espinosa's avatar
Arturo Espinosa committed
902
static Value *
903
904
gnumeric_log (struct FunctionDefinition *i,
	      Value *argv [], char **error_string)
905
906
907
{
	float_t t, base;

Michael Meeks's avatar
Michael Meeks committed
908
	t = value_get_as_float (argv [0]);
909
910
911
912

	if (argv[1] == NULL)
	        base = 10;
	else
Michael Meeks's avatar
Michael Meeks committed
913
	        base = value_get_as_float (argv[1]);
914
915

	if (t <= 0.0) {
Morten Welinder's avatar
Morten Welinder committed
916
		*error_string = gnumeric_err_VALUE;
917
918
919
		return NULL;
	}

Michael Meeks's avatar
Michael Meeks committed
920
	return value_new_float (log (t) / log (base));
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
}

static char *help_ln = {
	N_("@FUNCTION=LN\n"
	   "@SYNTAX=LN(x)\n"

	   "@DESCRIPTION="
	   "LN returns the natural logarithm of x. "
	   "\n"
	   "@SEEALSO=EXP, LOG2, LOG10")
};

static Value *
gnumeric_ln (struct FunctionDefinition *i,
	     Value *argv [], char **error_string)
Arturo Espinosa's avatar
Arturo Espinosa committed
936
937
938
{
	float_t t;

Michael Meeks's avatar
Michael Meeks committed
939
	t = value_get_as_float (argv [0]);
940

941
	if (t <= 0.0){
Morten Welinder's avatar
Morten Welinder committed
942
		*error_string = gnumeric_err_VALUE;
Arturo Espinosa's avatar
Arturo Espinosa committed
943
944
		return NULL;
	}
945

Michael Meeks's avatar
Michael Meeks committed
946
	return value_new_float (log (t));
Arturo Espinosa's avatar
Arturo Espinosa committed
947
948
}

949
950
951
952
953
static char *help_power = {
	N_("@FUNCTION=POWER\n"
	   "@SYNTAX=POWER(x,y)\n"

	   "@DESCRIPTION="
Morten Welinder's avatar
Morten Welinder committed
954
	   "Returns the value of x raised to the power y."
955
	   "\n"
Morten Welinder's avatar
Morten Welinder committed
956
	   "Performing this function on a string or empty cell returns an error."
957
958
959
960
961
	   "\n"
	   "@SEEALSO=EXP")
};

static Value *
962
963
gnumeric_power (struct FunctionDefinition *i,
		Value *argv [], char **error_string)
964
{
Morten Welinder's avatar
Morten Welinder committed
965
966
967
968
969
970
971
972
973
	float_t x, y;

	x = value_get_as_float (argv [0]);
	y = value_get_as_float (argv [1]);

	if ((x > 0) || (x == 0 && y > 0) || (x < 0 && y == floor (y)))
		return value_new_float (pow (x, y));

	/* FIXME: What is supposed to happen for x=y=0?  */
Morten Welinder's avatar
Morten Welinder committed
974
	*error_string = gnumeric_err_VALUE;
Morten Welinder's avatar
Morten Welinder committed
975
	return NULL;
976
977
}

978
static char *help_log2 = {
979
	N_("@FUNCTION=LOG2\n"
980
	   "@SYNTAX=LOG2(x)\n"
981
982

	   "@DESCRIPTION="
983
	   "Computes the base-2 logarithm  of x. "
984
985
986
987
988
989
	   "\n"
	   "Performing this function on a string or empty cell returns an error. "
	   "\n"
	   "@SEEALSO=EXP, LOG10, LOG")
};

Arturo Espinosa's avatar
Arturo Espinosa committed
990
static Value *
991
992
gnumeric_log2 (struct FunctionDefinition *i,
	       Value *argv [], char **error_string)
Arturo Espinosa's avatar
Arturo Espinosa committed
993
994
995
{
	float_t t;

Michael Meeks's avatar
Michael Meeks committed
996
	t = value_get_as_float (argv [0]);
997
	if (t <= 0.0){
Arturo Espinosa's avatar
Arturo Espinosa committed
998
999
1000
		*error_string = _("log2: domain error");
		return NULL;
	}
Michael Meeks's avatar
Michael Meeks committed
1001
	return value_new_float (log (t) / M_LN2);
Arturo Espinosa's avatar
Arturo Espinosa committed
1002
1003
}

1004
static char *help_log10 = {
1005
	N_("@FUNCTION=LOG10\n"
1006
	   "@SYNTAX=LOG10(x)\n"
1007
1008

	   "@DESCRIPTION="
1009
	   "Computes the base-10 logarithm  of x. "
1010
1011
1012
1013
1014
1015
1016
	   "\n"

	   "Performing this function on a string or empty cell returns an error. "
	   "\n"
	   "@SEEALSO=EXP, LOG2, LOG")
};

Arturo Espinosa's avatar
Arturo Espinosa committed
1017
static Value *
1018
1019
gnumeric_log10 (struct FunctionDefinition *i,
		Value *argv [], char **error_string)
Arturo Espinosa's avatar
Arturo Espinosa committed
1020
1021
1022
{
	float_t t;

Michael Meeks's avatar
Michael Meeks committed
1023
	t = value_get_as_float (argv [0]);
1024
	if (t <= 0.0){
Arturo Espinosa's avatar
Arturo Espinosa committed
1025
1026
1027
		*error_string = _("log10: domain error");
		return NULL;
	}
Michael Meeks's avatar
Michael Meeks committed
1028
	return value_new_float (log10 (t));
Arturo Espinosa's avatar
Arturo Espinosa committed
1029
1030
}

1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
static char *help_mod = {
	N_("@FUNCTION=MOD\n"
	   "@SYNTAX=MOD(number,divisor)\n"

	   "@DESCRIPTION="
	   "Implements modulo arithmetic."
	   "Returns the remainder when divisor is divided into abs(number)."
	   "\n"
	   "Returns #DIV/0! if divisor is zero."
	   "@SEEALSO=INT,FLOOR,CEIL")
};

static Value *
1044
1045
gnumeric_mod (struct FunctionDefinition *i,
	      Value *argv [], char **error_string)
1046
1047
{
	int a,b;
1048

1049
1050
	a = value_get_as_int (argv[0]);
	b = value_get_as_int (argv[1]);
1051
	/* Obscure handling of C's mod function */
1052
1053
1054
	if (a<0) a = -a;

	if (a < 0){ /* -0 */
Morten Welinder's avatar
Morten Welinder committed
1055
		*error_string = gnumeric_err_NUM;
1056
		return NULL;
1057
	}
1058
1059
1060
	if (b < 0){
		a = -a;
		b = -b;
1061
	}
1062
	if (b < 0) { /* -0 */
Morten Welinder's avatar
Morten Welinder committed
1063
		*error_string = gnumeric_err_NUM;
1064
		return NULL;
1065
	}
1066
	if (b == 0) {
Morten Welinder's avatar
Morten Welinder committed
1067
		*error_string = gnumeric_err_DIV0;
1068
		return NULL;
1069
	}
Morten Welinder's avatar
Morten Welinder committed
1070

1071
	return value_new_int (a % b);
1072
1073
}

1074
1075
static char *help_radians = {
	N_("@FUNCTION=RADIANS\n"
1076
	   "@SYNTAX=RADIANS(x)\n"
1077
1078

	   "@DESCRIPTION="
1079
1080
	   "Computes the number of radians equivalent to  "
	   "x degrees. "
1081
1082
1083
1084
	   "\n"

	   "Performing this function on a string or empty cell simply does nothing. "
	   "\n"
Morten Welinder's avatar
Morten Welinder committed
1085

1086
1087
	   "@SEEALSO=PI,DEGREES")
};
Arturo Espinosa's avatar
Arturo Espinosa committed
1088
1089

static Value *
1090
1091
gnumeric_radians (struct FunctionDefinition *i,
		  Value *argv [], char **error_string)
Arturo Espinosa's avatar
Arturo Espinosa committed
1092
{
Michael Meeks's avatar
Michael Meeks committed
1093
	return value_new_float ((value_get_as_float (argv [0]) * M_PI) / 180);
1094
}
Arturo Espinosa's avatar
Arturo Espinosa committed
1095

1096
1097
1098
1099
1100
1101
1102
1103
static char *help_rand = {
	N_("@FUNCTION=RAND\n"
	   "@SYNTAX=RAND()\n"

	   "@DESCRIPTION="
	   "Returns a random number greater than or equal to 0 and less than 1."
	   "\n"
	   "\n"
Morten Welinder's avatar
Morten Welinder committed
1104

1105
1106
1107
1108
	   "@SEEALSO=")
};

static Value *
1109
1110
gnumeric_rand (struct FunctionDefinition *i,
	       Value *argv [], char **error_string)
1111
{
Morten Welinder's avatar
Morten Welinder committed