Adaptive Framework  0.9.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
afw_function_double.c
Go to the documentation of this file.
1 // See the 'COPYING' file in the project root for licensing information.
2 /*
3  * afw_function_execute_* functions for Double
4  *
5  * Copyright (c) 2010-2023 Clemson University
6  *
7  */
8 
16 #include "afw_internal.h"
17 
22 /*
23  * Adaptive function: abs<double>
24  *
25  * afw_function_execute_abs_double
26  *
27  * See afw_function_bindings.h for more information.
28  *
29  * Compute the absolute value of the double value and return the double result.
30  *
31  * This function is pure, so it will always return the same result
32  * given exactly the same parameters and has no side effects.
33  *
34  * Declaration:
35  *
36  * ```
37  * function abs<double>(
38  * value: double
39  * ): double;
40  * ```
41  *
42  * Parameters:
43  *
44  * value - (double)
45  *
46  * Returns:
47  *
48  * (double)
49  */
50 const afw_value_t *
53 {
54  const afw_value_double_t *arg;
55 
57 
58  if (afw_number_is_NaN(arg->internal)) {
59  AFW_THROW_ERROR_Z(arg_error, "arg is not a number", x->xctx);
60  };
61  if (!afw_number_is_finite(arg->internal)) {
62  AFW_THROW_ERROR_Z(arg_error, "arg is infinite", x->xctx);
63  };
64 
65  return afw_value_create_double(fabs(arg->internal), x->p, x->xctx);
66 }
67 
68 
69 
70 /*
71  * Adaptive function: add<double>
72  *
73  * afw_function_execute_add_double
74  *
75  * See afw_function_bindings.h for more information.
76  *
77  * Add 2 or more double values and return the double result.
78  *
79  * This function is pure, so it will always return the same result
80  * given exactly the same parameters and has no side effects.
81  *
82  * Declaration:
83  *
84  * ```
85  * function add<double>(
86  * values_1: double,
87  * values_2: double,
88  * ...values_rest: (list of double)
89  * ): double;
90  * ```
91  *
92  * Parameters:
93  *
94  * values - (2 or more double)
95  *
96  * Returns:
97  *
98  * (double)
99  */
100 const afw_value_t *
103 {
104  const afw_value_double_t *arg;
105  double sum;
106  afw_size_t n;
107 
108  /* If sum become infinite before last parameter, error is thrown. */
109  for (sum = 0, n = 1; n <= x->argc; n++) {
111  sum += arg->internal;
112  }
113 
114  return afw_value_create_double(sum, x->p, x->xctx);
115 }
116 
117 
118 
119 /*
120  * Adaptive function: ceil<double>
121  *
122  * afw_function_execute_ceil_double
123  *
124  * See afw_function_bindings.h for more information.
125  *
126  * Determine the smallest integer that is greater then or equal to the double
127  * value and return the double result.
128  *
129  * This function is pure, so it will always return the same result
130  * given exactly the same parameters and has no side effects.
131  *
132  * Declaration:
133  *
134  * ```
135  * function ceil<double>(
136  * value: double
137  * ): double;
138  * ```
139  *
140  * Parameters:
141  *
142  * value - (double)
143  *
144  * Returns:
145  *
146  * (double)
147  */
148 const afw_value_t *
151 {
152  const afw_value_double_t *arg;
153 
155 
156  return afw_value_create_double(ceil(arg->internal), x->p, x->xctx);
157 }
158 
159 
160 
161 /*
162  * Adaptive function: divide<double>
163  *
164  * afw_function_execute_divide_double
165  *
166  * See afw_function_bindings.h for more information.
167  *
168  * Divide double dividend by double divisor and return the double quotient.
169  *
170  * This function is pure, so it will always return the same result
171  * given exactly the same parameters and has no side effects.
172  *
173  * Declaration:
174  *
175  * ```
176  * function divide<double>(
177  * dividend: double,
178  * divisor: double
179  * ): double;
180  * ```
181  *
182  * Parameters:
183  *
184  * dividend - (double)
185  *
186  * divisor - (double)
187  *
188  * Returns:
189  *
190  * (double)
191  */
192 const afw_value_t *
195 {
196  const afw_value_double_t *dividend;
197  const afw_value_double_t *divisor;
198 
201 
203  dividend->internal / divisor->internal, x->p, x->xctx);
204 }
205 
206 
207 
208 /*
209  * Adaptive function: is_finite
210  *
211  * afw_function_execute_is_finite
212  *
213  * See afw_function_bindings.h for more information.
214  *
215  * Checks if the argument 'number' is finite and returns the boolean result.
216  *
217  * This function is pure, so it will always return the same result
218  * given exactly the same parameters and has no side effects.
219  *
220  * Declaration:
221  *
222  * ```
223  * function is_finite(
224  * number: double
225  * ): boolean;
226  * ```
227  *
228  * Parameters:
229  *
230  * number - (double) Number to check.
231  *
232  * Returns:
233  *
234  * (boolean) True if the argument 'number' is finite.
235  */
236 const afw_value_t *
239 {
240  const afw_value_double_t *number;
241 
243 
244  return afw_number_is_finite(number->internal)
246  : afw_value_false;
247 }
248 
249 
250 
251 /*
252  * Adaptive function: floor<double>
253  *
254  * afw_function_execute_floor_double
255  *
256  * See afw_function_bindings.h for more information.
257  *
258  * Determine the largest integer that is smaller then or equal to the double
259  * value and return the double result.
260  *
261  * This function is pure, so it will always return the same result
262  * given exactly the same parameters and has no side effects.
263  *
264  * Declaration:
265  *
266  * ```
267  * function floor<double>(
268  * number: double
269  * ): double;
270  * ```
271  *
272  * Parameters:
273  *
274  * number - (double)
275  *
276  * Returns:
277  *
278  * (double)
279  */
280 const afw_value_t *
283 {
284  const afw_value_double_t *arg;
285 
287 
288  return afw_value_create_double(floor(arg->internal), x->p, x->xctx);
289 }
290 
291 
292 
293 /*
294  * Adaptive function: multiply<double>
295  *
296  * afw_function_execute_multiply_double
297  *
298  * See afw_function_bindings.h for more information.
299  *
300  * Multiply 2 or more double values and return the double result.
301  *
302  * This function is pure, so it will always return the same result
303  * given exactly the same parameters and has no side effects.
304  *
305  * Declaration:
306  *
307  * ```
308  * function multiply<double>(
309  * values_1: double,
310  * values_2: double,
311  * ...values_rest: (list of double)
312  * ): double;
313  * ```
314  *
315  * Parameters:
316  *
317  * values - (2 or more double)
318  *
319  * Returns:
320  *
321  * (double)
322  */
323 const afw_value_t *
326 {
327  const afw_value_double_t *arg;
328  double result;
329  afw_size_t n;
330 
331  /* Loop multiplying parameters. */
332  for (result = 1, n = 1; n <= x->argc; n++) {
334  result *= arg->internal;
335  }
336 
337  return afw_value_create_double(result, x->p, x->xctx);
338 }
339 
340 
341 
342 /*
343  * Adaptive function: is_NaN
344  *
345  * afw_function_execute_is_NaN
346  *
347  * See afw_function_bindings.h for more information.
348  *
349  * Checks if the argument 'number' is not a number(NaN) and returns the boolean
350  * result.
351  *
352  * This function is pure, so it will always return the same result
353  * given exactly the same parameters and has no side effects.
354  *
355  * Declaration:
356  *
357  * ```
358  * function is_NaN(
359  * number: double
360  * ): boolean;
361  * ```
362  *
363  * Parameters:
364  *
365  * number - (double) Number to check.
366  *
367  * Returns:
368  *
369  * (boolean) True if the argument 'number' is not a number.
370  */
371 const afw_value_t *
374 {
375  const afw_value_double_t *number;
376 
378 
379  return afw_number_is_NaN(number->internal)
381  : afw_value_false;
382 }
383 
384 
385 
386 /*
387  * Adaptive function: pow<double>
388  *
389  * afw_function_execute_pow_double
390  *
391  * See afw_function_bindings.h for more information.
392  *
393  * This returns the value of base raised to a power. Multiple exponents can be
394  * specified to raise the previous exponent to the power of the latter
395  * exponent.
396  *
397  * This function is pure, so it will always return the same result
398  * given exactly the same parameters and has no side effects.
399  *
400  * Declaration:
401  *
402  * ```
403  * function pow<double>(
404  * base: double,
405  * exponent_1: double,
406  * ...exponent_rest: (list of double)
407  * ): double;
408  * ```
409  *
410  * Parameters:
411  *
412  * base - (double) Base value.
413  *
414  * exponent - (1 or more double) Exponent value.
415  *
416  * Returns:
417  *
418  * (double) Base raised to the power.
419  */
420 const afw_value_t *
423 {
424  const afw_value_double_t *base;
425  const afw_value_double_t *exponent;
426  afw_value_double_t *result;
427  afw_size_t i;
428 
430  x->argc, double);
431  result = afw_value_allocate_double(x->p, x->xctx);
432 
433  for (i = x->argc - 1; i >= 1; i--) {
435  /*
436  * If absolute value of base is 1, and exponent is Infinity, then result
437  * is NaN.
438  */
439  if (fabs(base->internal) == 1.0 &&
440  !afw_number_is_finite(exponent->internal))
441  {
442  result->internal = x->xctx->env->NaN;
443  break;
444  }
445  else {
446  result->internal = pow(base->internal, exponent->internal);
447  if (!afw_number_is_finite(result->internal)) {
448  break;
449  }
450  exponent = (const afw_value_double_t *)result;
451  }
452  }
453 
454  return (const afw_value_t *)result;
455 }
456 
457 
458 
459 /*
460  * Adaptive function: round<double>
461  *
462  * afw_function_execute_round_double
463  *
464  * See afw_function_bindings.h for more information.
465  *
466  * Determine the integer closest to double value and return the double result.
467  *
468  * This function is pure, so it will always return the same result
469  * given exactly the same parameters and has no side effects.
470  *
471  * Declaration:
472  *
473  * ```
474  * function round<double>(
475  * number: double
476  * ): double;
477  * ```
478  *
479  * Parameters:
480  *
481  * number - (double)
482  *
483  * Returns:
484  *
485  * (double)
486  */
487 const afw_value_t *
490 {
491  const afw_value_double_t *arg;
492 
494 
495  /* Note: Uses round(), which seems right. Might should use rint()? */
496  return afw_value_create_double(round(arg->internal), x->p, x->xctx);
497 }
498 
499 
500 
501 /*
502  * Adaptive function: subtract<double>
503  *
504  * afw_function_execute_subtract_double
505  *
506  * See afw_function_bindings.h for more information.
507  *
508  * Subtract double arg2 from double arg1 and return the double result.
509  *
510  * This function is pure, so it will always return the same result
511  * given exactly the same parameters and has no side effects.
512  *
513  * Declaration:
514  *
515  * ```
516  * function subtract<double>(
517  * arg1: double,
518  * arg2: double
519  * ): double;
520  * ```
521  *
522  * Parameters:
523  *
524  * arg1 - (double)
525  *
526  * arg2 - (double)
527  *
528  * Returns:
529  *
530  * (double)
531  */
532 const afw_value_t *
535 {
536  const afw_value_double_t *arg1;
537  const afw_value_double_t *arg2;
538 
541 
542  return afw_value_create_double(arg1->internal - arg2->internal,
543  x->p, x->xctx);
544 }
545 
546 
547 
548 /*
549  * Adaptive function: to_integer<double>
550  *
551  * afw_function_execute_to_integer_double
552  *
553  * See afw_function_bindings.h for more information.
554  *
555  * Truncate double arg to a whole number and returns integer result.
556  *
557  * This function is pure, so it will always return the same result
558  * given exactly the same parameters.
559  *
560  * Parameters:
561  * arg - (double)
562  *
563  * Returns:
564  * (integer)
565  */
566 const afw_value_t *
569 {
570  const afw_value_double_t *arg;
571  double d;
572 
574 
575  if (afw_number_is_NaN(arg->internal)) {
576  AFW_THROW_ERROR_Z(arg_error, "arg is not a number", x->xctx);
577  };
578  if (!afw_number_is_finite(arg->internal)) {
579  AFW_THROW_ERROR_Z(arg_error, "arg is infinite", x->xctx);
580  };
581 
582  d = trunc(arg->internal);
583  return afw_value_create_integer((afw_integer_t)d, x->p, x->xctx);
584 }
585 
586 
587 
588 /*
589  * Adaptive function: negative<double>
590  *
591  * afw_function_execute_negative_double
592  *
593  * See afw_function_bindings.h for more information.
594  *
595  * Return negative of double value.
596  *
597  * This function is pure, so it will always return the same result
598  * given exactly the same parameters and has no side effects.
599  *
600  * Declaration:
601  *
602  * ```
603  * function negative<double>(
604  * value: double
605  * ): double;
606  * ```
607  *
608  * Parameters:
609  *
610  * value - (double)
611  *
612  * Returns:
613  *
614  * (double)
615  */
616 const afw_value_t *
619 {
620  const afw_value_double_t *arg;
621 
623 
624  return afw_value_create_double(-arg->internal, x->p, x->xctx);
625 }
Adaptive Framework Core Internal.
afw_value_allocate_double(const afw_pool_t *p, afw_xctx_t *xctx)
Allocate function for unmanaged data type double value.
afw_value_create_double(double internal, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for unmanaged data type double value.
afw_value_create_integer(afw_integer_t internal, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for unmanaged data type integer value.
apr_size_t afw_size_t
size_t.
Definition: afw_common.h:151
apr_int64_t afw_integer_t
typedef for big signed int.
Definition: afw_common.h:321
#define AFW_THROW_ERROR_Z(code, message_z, xctx)
Macro used to set error and 0 rv in xctx and throw it.
Definition: afw_error.h:283
#define AFW_FUNCTION_EVALUATE_REQUIRED_DATA_TYPE_PARAMETER(A_RESULT, A_N, A_TYPE)
Evaluate an arg for a particular data type.
Definition: afw_function.h:328
const afw_value_t * afw_function_execute_ceil_double(afw_function_execute_t *x)
Adaptive Function ceil<double>
const afw_value_t * afw_function_execute_add_double(afw_function_execute_t *x)
Adaptive Function add<double>
const afw_value_t * afw_function_execute_is_NaN(afw_function_execute_t *x)
Adaptive Function is_NaN
const afw_value_t * afw_function_execute_divide_double(afw_function_execute_t *x)
Adaptive Function divide<double>
const afw_value_t * afw_function_execute_round_double(afw_function_execute_t *x)
Adaptive Function round<double>
const afw_value_t * afw_function_execute_floor_double(afw_function_execute_t *x)
Adaptive Function floor<double>
const afw_value_t * afw_function_execute_negative_double(afw_function_execute_t *x)
Adaptive Function negative<double>
const afw_value_t * afw_function_execute_is_finite(afw_function_execute_t *x)
Adaptive Function is_finite
const afw_value_t * afw_function_execute_subtract_double(afw_function_execute_t *x)
Adaptive Function subtract<double>
const afw_value_t * afw_function_execute_pow_double(afw_function_execute_t *x)
Adaptive Function pow<double>
const afw_value_t * afw_function_execute_multiply_double(afw_function_execute_t *x)
Adaptive Function multiply<double>
const afw_value_t * afw_function_execute_abs_double(afw_function_execute_t *x)
Adaptive Function abs<double>
const afw_value_t * afw_function_execute_to_integer_double(afw_function_execute_t *x)
Function implementation function afw_function_execute_to_integer_double.
afw_boolean_t afw_number_is_NaN(double d)
Determine if double is not a number.
Definition: afw_number.h:84
afw_boolean_t afw_number_is_finite(double d)
Determine if double is finite.
Definition: afw_number.h:45
afw_value_false
Adaptive value false.
Definition: afw_value.h:354
afw_value_true
Adaptive value true.
Definition: afw_value.h:348
afw_double_t NaN
Double NaN.
Definition: afw_common.h:1443
Function execute parameter.
Definition: afw_function.h:53
afw_xctx_t * xctx
The execution context (xctx) of caller.
Definition: afw_function.h:62
const afw_pool_t * p
Pool for result.
Definition: afw_function.h:59
afw_size_t argc
This is the argv count not counting argv[0].
Definition: afw_function.h:89
struct for data type double values.
Interface afw_value public struct.