From 64fdb009695828b788fce074135b20a5e52c5fc4 Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Tue, 23 Sep 2003 00:21:28 +0000 Subject: imported version 0.37-0 svn path=/trunk/; revision=1016 --- pd/extra/expr~/vexp_fun.c | 611 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 549 insertions(+), 62 deletions(-) (limited to 'pd/extra/expr~/vexp_fun.c') diff --git a/pd/extra/expr~/vexp_fun.c b/pd/extra/expr~/vexp_fun.c index 2879d96b..53e9092f 100644 --- a/pd/extra/expr~/vexp_fun.c +++ b/pd/extra/expr~/vexp_fun.c @@ -24,8 +24,42 @@ * */ -/* "expr" was written by Shahrokh Yadegari c. 1989. -msp */ -/* Nov. 2001 - conversion for expr~ --sdy */ +/* "expr" was written by Shahrokh Yadegari c. 1989. -msp + * + * Nov. 2001 --sdy + * conversion for expr~ + * + * Jan, 2002 --sdy + * added fmod() + * + * May 2002 + * added floor and ceil for expr -- Orm Finnendahl + * + * July 2002 --sdy + * added the following math funtions: + * cbrt - cube root + * erf - error function + * erfc - complementary error function + * expm1 - exponential minus 1, + * log1p - logarithm of 1 plus + * isinf - is the value infinite, + * finite - is the value finite + * isnan -- is the resut a nan (Not a number) + * copysign - copy sign of a number + * ldexp - multiply floating-point number by integral power of 2 + * imodf - get signed integral value from floating-point number + * modf - get signed fractional value from floating-point number + * drem - floating-point remainder function + * + * The following are done but not popular enough in math libss + * to be included yet + * hypoth - Euclidean distance function + * trunc + * round + * nearbyint - + */ + + /* * vexp_func.c -- this file include all the functions for vexp. @@ -45,6 +79,7 @@ */ #include +#include #define __STRICT_BSD__ #include @@ -81,6 +116,33 @@ static void ex_sqrt(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_e static void ex_fact(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_random(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_abs(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); +static void ex_fmod(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); +static void ex_ceil(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); +static void ex_floor(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); +static void ex_if(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); +static void ex_ldexp(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); +static void ex_imodf(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); +static void ex_modf(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); +#ifndef NT +static void ex_cbrt(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); +static void ex_erf(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); +static void ex_erfc(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); +static void ex_expm1(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); +static void ex_log1p(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); +static void ex_isinf(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); +static void ex_finite(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); +static void ex_isnan(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); +static void ex_copysign(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); +static void ex_drem(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); +#endif +#ifdef notdef +/* the following will be added once they are more popular in math libraries */ +static void ex_round(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); +static void ex_trunc(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); +static void ex_nearbyint(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); +static void ex_hypoth(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); +#endif + t_ex_func ex_funcs[] = { {"min", ex_min, 2}, @@ -88,6 +150,9 @@ t_ex_func ex_funcs[] = { {"int", ex_toint, 1}, {"rint", ex_rint, 1}, {"float", ex_tofloat, 1}, + {"fmod", ex_fmod, 2}, + {"floor", ex_floor, 2}, + {"ceil", ex_ceil, 2}, {"pow", ex_pow, 2}, {"sqrt", ex_sqrt, 1}, {"exp", ex_exp, 1}, @@ -107,7 +172,21 @@ t_ex_func ex_funcs[] = { {"fact", ex_fact, 1}, {"random", ex_random, 2}, /* random number */ {"abs", ex_abs, 1}, + {"if", ex_if, 3}, + {"ldexp ", ex_ldexp, 1}, + {"imodf ", ex_imodf, 1}, + {"modf", ex_modf, 1}, #ifndef NT + {"cbrt", ex_cbrt, 1}, + {"erf", ex_erf, 1}, + {"erfc", ex_erfc, 1}, + {"expm1", ex_expm1, 1}, + {"log1p", ex_log1p, 1}, + {"isinf", ex_isinf, 1}, + {"finite", ex_finite, 1}, + {"isnan", ex_isnan, 1}, + {"copysig", ex_copysign, 1}, + {"drem", ex_drem, 1}, {"asinh", ex_asinh, 1}, {"acosh", ex_acosh, 1}, {"atanh", ex_atanh, 1}, /* hyperbolic atan */ @@ -119,14 +198,23 @@ t_ex_func ex_funcs[] = { {"avg", ex_avg, 1}, {"Avg", ex_Avg, 3}, {"store", ex_store, 3}, +#endif +#ifdef notdef +/* the following will be added once they are more popular in math libraries */ + {"round", ex_round, 1}, + {"trunc", ex_trunc, 1}, + {"nearbyint", ex_nearbyint, 1}, + {"hypoth", ex_hypoth, 1}, #endif {0, 0, 0} }; /* - * FUN_EVAL -- + * FUN_EVAL -- do type checking, evaluate a function, + * if fltret is set return float + * otherwise return value based on regular typechecking, */ -#define FUNC_EVAL(left, right, func, leftfuncast, rightfuncast, optr) \ +#define FUNC_EVAL(left, right, func, leftfuncast, rightfuncast, optr, fltret) \ switch (left->ex_type) { \ case ET_INT: \ switch(right->ex_type) { \ @@ -139,9 +227,15 @@ case ET_INT: \ while (j--) \ *op++ = scalar; \ } else { \ - optr->ex_type = ET_INT; \ - optr->ex_int = (int)func(leftfuncast left->ex_int, \ - rightfuncast right->ex_int); \ + if (fltret) { \ + optr->ex_type = ET_FLT; \ + optr->ex_flt = (float)func(leftfuncast \ + left->ex_int, rightfuncast right->ex_int); \ + } else { \ + optr->ex_type = ET_INT; \ + optr->ex_int = (int)func(leftfuncast \ + left->ex_int, rightfuncast right->ex_int); \ + } \ } \ break; \ case ET_FLT: \ @@ -197,8 +291,8 @@ case ET_FLT: \ while (j--) \ *op++ = scalar; \ } else { \ - optr->ex_type = ET_INT; \ - optr->ex_int = (int)func(leftfuncast left->ex_flt, \ + optr->ex_type = ET_FLT; \ + optr->ex_flt = (float)func(leftfuncast left->ex_flt, \ rightfuncast right->ex_int); \ } \ break; \ @@ -306,9 +400,11 @@ default: \ } /* - * evaluate a unary operator, TYPE is applied to float operands + * FUNC_EVAL_UNARY - evaluate a unary function, + * if fltret is set return float + * otherwise return value based on regular typechecking, */ -#define FUNC_EVAL_UNARY(left, func, leftcast, optr) \ +#define FUNC_EVAL_UNARY(left, func, leftcast, optr, fltret) \ switch(left->ex_type) { \ case ET_INT: \ if (optr->ex_type == ET_VEC) { \ @@ -316,6 +412,11 @@ case ET_INT: \ (float)(func (leftcast left->ex_int)), e->exp_vsize);\ break; \ } \ + if (fltret) { \ + optr->ex_type = ET_FLT; \ + optr->ex_flt = (float) func(leftcast left->ex_int); \ + break; \ + } \ optr->ex_type = ET_INT; \ optr->ex_int = (int) func(leftcast left->ex_int); \ break; \ @@ -352,8 +453,39 @@ default: \ #define min(x,y) (x > y ? y : x) #define max(x,y) (x > y ? x : y) +#define FUNC_DEF(ex_func, func, castleft, castright, fltret); \ +static void \ +ex_func(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)\ +{ \ + struct ex_ex *left, *right; \ + float *op; /* output pointer */ \ + float *lp, *rp; /* left and right vector pointers */ \ + float scalar; \ + int j; \ + \ + left = argv++; \ + right = argv; \ + FUNC_EVAL(left, right, func, castleft, castright, optr, fltret); \ +} + + +#define FUNC_DEF_UNARY(ex_func, func, cast, fltret); \ +static void \ +ex_func(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)\ +{ \ + struct ex_ex *left; \ + float *op; /* output pointer */ \ + float *lp, *rp; /* left and right vector pointers */ \ + float scalar; \ + int j; \ + \ + left = argv++; \ + \ + FUNC_EVAL_UNARY(left, func, cast, optr, fltret); \ +} + /* - * ex_min -- if any of the arfuments are or the output are vectors, a vector + * ex_min -- if any of the arguments are or the output are vectors, a vector * of floats is generated otherwise the type of the result is the * type of the smaller value */ @@ -369,12 +501,11 @@ ex_min(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) left = argv++; right = argv; - /* minimum needs no cast, as it is not a real function */ - FUNC_EVAL(left, right, min, (double), (double), optr); + FUNC_EVAL(left, right, min, (double), (double), optr, 0); } /* - * ex_max -- if any of the arfuments are or the output are vectors, a vector + * ex_max -- if any of the arguments are or the output are vectors, a vector * of floats is generated otherwise the type of the result is the * type of the larger value */ @@ -390,12 +521,9 @@ ex_max(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) left = argv++; right = argv; - /* minimum needs no cast, as it is not a real function */ - FUNC_EVAL(left, right, max, (double), (double), optr); + FUNC_EVAL(left, right, max, (double), (double), optr, 0); } -/* SDY changed to new form up to here */ - /* * ex_toint -- convert to integer */ @@ -411,8 +539,8 @@ ex_toint(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) left = argv++; #define toint(x) ((int)(x)) - FUNC_EVAL_UNARY(left, toint, (int), optr); -} + FUNC_EVAL_UNARY(left, toint, (int), optr, 0); + } #ifdef NT /* No rint in NT land ??? */ @@ -441,25 +569,7 @@ ex_rint(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) left = argv++; - FUNC_EVAL_UNARY(left, rint, (double), optr); - -#ifdef old - - if (argv->ex_type == ET_INT) - *optr = *argv; - else if (argv->ex_type == ET_FLT) { - optr->ex_type = ET_FLT; -#ifdef NT /* no rint() in NT??? */ - optr->ex_flt = floor(argv->ex_flt + 0.5); -#else - optr->ex_flt = rint(argv->ex_flt); -#endif - } else { -/* SDY what does this mean? this is wrong!!???? */ - optr->ex_type = ET_INT; - optr->ex_int = (int)argv->ex_ptr; - } -#endif + FUNC_EVAL_UNARY(left, rint, (double), optr, 1); } /* @@ -477,7 +587,7 @@ ex_tofloat(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) left = argv++; #define tofloat(x) ((float)(x)) - FUNC_EVAL_UNARY(left, toint, (int), optr); + FUNC_EVAL_UNARY(left, tofloat, (int), optr, 1); } @@ -495,7 +605,7 @@ ex_pow(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) left = argv++; right = argv; - FUNC_EVAL(left, right, pow, (double), (double), optr); + FUNC_EVAL(left, right, pow, (double), (double), optr, 1); } /* @@ -512,7 +622,7 @@ ex_sqrt(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) left = argv++; - FUNC_EVAL_UNARY(left, sqrt, (double), optr); + FUNC_EVAL_UNARY(left, sqrt, (double), optr, 1); } /* @@ -529,7 +639,7 @@ ex_exp(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) left = argv++; - FUNC_EVAL_UNARY(left, exp, (double), optr); + FUNC_EVAL_UNARY(left, exp, (double), optr, 1); } /* @@ -546,7 +656,7 @@ ex_log(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) left = argv++; - FUNC_EVAL_UNARY(left, log10, (double), optr); + FUNC_EVAL_UNARY(left, log10, (double), optr, 1); } /* @@ -563,7 +673,7 @@ ex_ln(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) left = argv++; - FUNC_EVAL_UNARY(left, log, (double), optr); + FUNC_EVAL_UNARY(left, log, (double), optr, 1); } static void @@ -577,7 +687,7 @@ ex_sin(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) left = argv++; - FUNC_EVAL_UNARY(left, sin, (double), optr); + FUNC_EVAL_UNARY(left, sin, (double), optr, 1); } static void @@ -591,7 +701,7 @@ ex_cos(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) left = argv++; - FUNC_EVAL_UNARY(left, cos, (double), optr); + FUNC_EVAL_UNARY(left, cos, (double), optr, 1); } @@ -606,7 +716,7 @@ ex_tan(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) left = argv++; - FUNC_EVAL_UNARY(left, tan, (double), optr); + FUNC_EVAL_UNARY(left, tan, (double), optr, 1); } static void @@ -620,7 +730,7 @@ ex_asin(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) left = argv++; - FUNC_EVAL_UNARY(left, asin, (double), optr); + FUNC_EVAL_UNARY(left, asin, (double), optr, 1); } static void @@ -634,7 +744,7 @@ ex_acos(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) left = argv++; - FUNC_EVAL_UNARY(left, acos, (double), optr); + FUNC_EVAL_UNARY(left, acos, (double), optr, 1); } @@ -649,7 +759,7 @@ ex_atan(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) left = argv++; - FUNC_EVAL_UNARY(left, atan, (double), optr); + FUNC_EVAL_UNARY(left, atan, (double), optr, 1); } /* @@ -666,9 +776,59 @@ ex_atan2(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) left = argv++; right = argv; - FUNC_EVAL(left, right, atan2, (double), (double), optr); + FUNC_EVAL(left, right, atan2, (double), (double), optr, 1); } +/* + * ex_fmod -- floating point modulo + */ +static void +ex_fmod(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) +{ + struct ex_ex *left, *right; + float *op; /* output pointer */ + float *lp, *rp; /* left and right vector pointers */ + float scalar; + int j; + + left = argv++; + right = argv; + FUNC_EVAL(left, right, fmod, (double), (double), optr, 1); +} + + +/* + * ex_floor -- floor + */ +static void +ex_floor(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) +{ + struct ex_ex *left; + float *op; /* output pointer */ + float *lp, *rp; /* left and right vector pointers */ + float scalar; + int j; + + left = argv++; + FUNC_EVAL_UNARY(left, floor, (double), optr, 1); +} + + +/* + * ex_ceil -- ceil + */ +static void +ex_ceil(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) +{ + struct ex_ex *left; + float *op; /* output pointer */ + float *lp, *rp; /* left and right vector pointers */ + float scalar; + int j; + + left = argv++; + FUNC_EVAL_UNARY(left, ceil, (double), optr, 1); +} static void ex_sinh(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) @@ -681,7 +841,7 @@ ex_sinh(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) left = argv++; - FUNC_EVAL_UNARY(left, sinh, (double), optr); + FUNC_EVAL_UNARY(left, sinh, (double), optr, 1); } static void @@ -695,7 +855,7 @@ ex_cosh(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) left = argv++; - FUNC_EVAL_UNARY(left, cosh, (double), optr); + FUNC_EVAL_UNARY(left, cosh, (double), optr, 1); } @@ -710,7 +870,7 @@ ex_tanh(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) left = argv++; - FUNC_EVAL_UNARY(left, tanh, (double), optr); + FUNC_EVAL_UNARY(left, tanh, (double), optr, 1); } @@ -726,7 +886,7 @@ ex_asinh(t_expr *e, long argc, struct ex_ex *argv, struct ex_ex *optr) left = argv++; - FUNC_EVAL_UNARY(left, asinh, (double), optr); + FUNC_EVAL_UNARY(left, asinh, (double), optr, 1); } static void @@ -740,7 +900,7 @@ ex_acosh(t_expr *e, long argc, struct ex_ex *argv, struct ex_ex *optr) left = argv++; - FUNC_EVAL_UNARY(left, acosh, (double), optr); + FUNC_EVAL_UNARY(left, acosh, (double), optr, 1); } static void @@ -754,7 +914,7 @@ ex_atanh(t_expr *e, long argc, struct ex_ex *argv, struct ex_ex *optr) left = argv++; - FUNC_EVAL_UNARY(left, atanh, (double), optr); + FUNC_EVAL_UNARY(left, atanh, (double), optr, 1); } #endif @@ -786,7 +946,7 @@ ex_fact(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) left = argv++; - FUNC_EVAL_UNARY(left, ex_dofact, (int), optr); + FUNC_EVAL_UNARY(left, ex_dofact, (int), optr, 0); } static int @@ -808,7 +968,7 @@ ex_random(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) left = argv++; right = argv; - FUNC_EVAL(left, right, ex_dorandom, (int), (int), optr); + FUNC_EVAL(left, right, ex_dorandom, (int), (int), optr, 0); } @@ -823,6 +983,333 @@ ex_abs(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) left = argv++; - FUNC_EVAL_UNARY(left, fabs, (double), optr); + FUNC_EVAL_UNARY(left, fabs, (double), optr, 0); } +/* + *ex_if -- floating point modulo + */ +static void +ex_if(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) +{ + struct ex_ex *left, *right, *cond, *res; + float *op; /* output pointer */ + float *lp, *rp; /* left and right vector pointers */ + float *cp; /* condition pointer */ + float leftvalue, rightvalue; + int j; + + cond = argv++; + left = argv++; + right = argv; + + switch (cond->ex_type) { + case ET_VEC: + case ET_VI: + if (optr->ex_type != ET_VEC) { + if (optr->ex_type == ET_VI) { + /* SDY remove this test */ + post("expr~: Int. error %d", __LINE__); + return; + } + optr->ex_type = ET_VEC; + optr->ex_vec = (t_float *) + fts_malloc(sizeof (t_float) * e->exp_vsize); + } + op = optr->ex_vec; + j = e->exp_vsize; + cp = cond->ex_vec; + switch (left->ex_type) { + case ET_INT: + leftvalue = left->ex_int; + switch (right->ex_type) { + case ET_INT: + rightvalue = right->ex_int; + while (j--) { + if (*cp++) + *op++ = leftvalue; + else + *op++ = rightvalue; + } + return; + case ET_FLT: + rightvalue = right->ex_flt; + while (j--) { + if (*cp++) + *op++ = leftvalue; + else + *op++ = rightvalue; + } + return; + case ET_VEC: + case ET_VI: + rp = right->ex_vec; + while (j--) { + if (*cp++) + *op++ = leftvalue; + else + *op++ = *rp; + rp++; + } + return; + case ET_SYM: + default: + post_error((fts_object_t *) e, + "expr: FUNC_EVAL(%d): bad right type %ld\n", + __LINE__, right->ex_type); + return; + } + case ET_FLT: + leftvalue = left->ex_flt; + switch (right->ex_type) { + case ET_INT: + rightvalue = right->ex_int; + while (j--) { + if (*cp++) + *op++ = leftvalue; + else + *op++ = rightvalue; + } + return; + case ET_FLT: + rightvalue = right->ex_flt; + while (j--) { + if (*cp++) + *op++ = leftvalue; + else + *op++ = rightvalue; + } + return; + case ET_VEC: + case ET_VI: + rp = right->ex_vec; + while (j--) { + if (*cp++) + *op++ = leftvalue; + else + *op++ = *rp; + rp++; + } + return; + case ET_SYM: + default: + post_error((fts_object_t *) e, + "expr: FUNC_EVAL(%d): bad right type %ld\n", + __LINE__, right->ex_type); + return; + } + case ET_VEC: + case ET_VI: + lp = left->ex_vec; + switch (right->ex_type) { + case ET_INT: + rightvalue = right->ex_int; + while (j--) { + if (*cp++) + *op++ = *lp; + else + *op++ = rightvalue; + lp++; + } + return; + case ET_FLT: + rightvalue = right->ex_flt; + while (j--) { + if (*cp++) + *op++ = *lp; + else + *op++ = rightvalue; + lp++; + } + return; + case ET_VEC: + case ET_VI: + rp = right->ex_vec; + while (j--) { + if (*cp++) + *op++ = *lp; + else + *op++ = *rp; + lp++; rp++; + } + return; + case ET_SYM: + default: + post_error((fts_object_t *) e, + "expr: FUNC_EVAL(%d): bad right type %ld\n", + __LINE__, right->ex_type); + return; + } + case ET_SYM: + default: + post_error((fts_object_t *) e, + "expr: FUNC_EVAL(%d): bad left type %ld\n", + __LINE__, left->ex_type); + return; + } + case ET_INT: + if (cond->ex_int) + res = left; + else + res = right; + break; + case ET_FLT: + if (cond->ex_flt) + res = left; + else + res = right; + break; + case ET_SYM: + default: + post_error((fts_object_t *) e, + "expr: FUNC_EVAL(%d): bad condition type %ld\n", + __LINE__, cond->ex_type); + return; + } + switch(res->ex_type) { + case ET_INT: + if (optr->ex_type == ET_VEC) { + ex_mkvector(optr->ex_vec, (float)res->ex_int, + e->exp_vsize); + return; + } + *optr = *res; + return; + case ET_FLT: + if (optr->ex_type == ET_VEC) { + ex_mkvector(optr->ex_vec, (float)res->ex_flt, + e->exp_vsize); + return; + } + *optr = *res; + return; + case ET_VEC: + case ET_VI: + if (optr->ex_type != ET_VEC) { + if (optr->ex_type == ET_VI) { + /* SDY remove this test */ + post("expr~: Int. error %d", __LINE__); + return; + } + optr->ex_type = ET_VEC; + optr->ex_vec = (t_float *) + fts_malloc(sizeof (t_float) * e->exp_vsize); + } + memcpy(optr->ex_vec, res->ex_vec, e->exp_vsize*sizeof(t_float)); + return; + case ET_SYM: + default: + post_error((fts_object_t *) e, + "expr: FUNC_EVAL(%d): bad res type %ld\n", + __LINE__, res->ex_type); + return; + } + +} + +/* + * ex_imodf - extract signed integral value from floating-point number + */ +static double +imodf(double x) +{ + double xx; + + modf(x, &xx); + return (xx); +} +FUNC_DEF_UNARY(ex_imodf, imodf, (double), 1); + +/* + * ex_modf - extract signed fractional value from floating-point number + * + * using fracmodf because fmodf() is alrady defined in a .h file + */ +static double +fracmodf(double x) +{ + double xx; + + return(modf(x, &xx)); +} +FUNC_DEF_UNARY(ex_modf, fracmodf, (double), 1); + +/* + * ex_ldexp - multiply floating-point number by integral power of 2 + */ +FUNC_DEF(ex_ldexp, ldexp, (double), (int), 1); + +#ifndef NT +/* + * ex_cbrt - cube root + */ +FUNC_DEF_UNARY(ex_cbrt, cbrt, (double), 1); + +/* + * ex_erf - error function + */ +FUNC_DEF_UNARY(ex_erf, erf, (double), 1); + +/* + * ex_erfc - complementary error function + */ +FUNC_DEF_UNARY(ex_erfc, erfc, (double), 1); + +/* + * ex_expm1 - exponential minus 1, + */ +FUNC_DEF_UNARY(ex_expm1, expm1, (double), 1); + +/* + * ex_log1p - logarithm of 1 plus + */ +FUNC_DEF_UNARY(ex_log1p, log1p, (double), 1); + +/* + * ex_isinf - is the value infinite, + */ +FUNC_DEF_UNARY(ex_isinf, isinf, (double), 0); + +/* + * ex_finite - is the value finite + */ +FUNC_DEF_UNARY(ex_finite, finite, (double), 0); + +/* + * ex_isnan -- is the resut a nan (Not a number) + */ +FUNC_DEF_UNARY(ex_isnan, isnan, (double), 0); + +/* + * ex_copysign - copy sign of a number + */ +FUNC_DEF(ex_copysign, copysign, (double), (double), 1); + +/* + * ex_drem - floating-point remainder function + */ +FUNC_DEF(ex_drem, drem, (double), (double), 1); +#endif + +#ifdef notdef +/* the following will be added once they are more popular in math libraries */ +/* + * ex_hypoth - Euclidean distance function + */ +FUNC_DEF(ex_hypoth, hypoth, (double), (double), 1); + +/* + * ex_round - round to nearest integer, away from zero + */ +FUNC_DEF_UNARY(ex_round, round, (double), 1); + +/* + * ex_trunc - round to interger, towards zero + */ +FUNC_DEF_UNARY(ex_trunc, trunc, (double), 1); + +/* + * ex_nearbyint - round to nearest integer + */ +FUNC_DEF_UNARY(ex_nearbyint, nearbyint, (double), 1); +#endif -- cgit v1.2.1