/* For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. iem_dp written by IOhannes m zmoelnig, Thomas Musil, Copyright (c) IEM KUG Graz Austria 1999 - 2013 */ /* double precision library */ #include "m_pd.h" #include "iemlib.h" #include "iem_dp.h" #include #include #include /* -------------------------- symtodp ------------------------------ */ /* symbol double precision number to double float converter */ /* double float is only internal used */ /* to transfer this value, we divide this double value into use one float casted value */ /* and into the difference to the accurate double value. */ /* double float (sign_1 + exp_12 + mant_51) */ static t_class *symtodp_class; typedef struct _symtodp { t_object x_obj; double x_inner_double_value; t_outlet *x_out_floatcasted; t_outlet *x_out_residual; } t_symtodp; static double symtodp_calc_list_sum(int ac, t_atom *av) { int i; char str[1000], buf[100], *dummy; str[0] = 0; for(i=0; ix_inner_double_value); outlet_float(x->x_out_residual, iem_dp_calc_residual(x->x_inner_double_value, float_casted_value)); outlet_float(x->x_out_floatcasted, float_casted_value); } static void symtodp_float(t_symtodp *x, t_floatarg f) { x->x_inner_double_value = (double)f; symtodp_bang(x); } static void symtodp_symbol(t_symtodp *x, t_symbol *s) { char *dummy; if((s->s_name[0] == '"') && (s->s_name[1])) { if((s->s_name[1] == '.') || (s->s_name[1] == '+') || (s->s_name[1] == '-') || ((s->s_name[1] >= '0') && (s->s_name[1] <= '9'))) { x->x_inner_double_value = strtod(s->s_name+1, &dummy); symtodp_bang(x); } } else if((s->s_name[0] == '.') || (s->s_name[0] == '+') || (s->s_name[0] == '-') || ((s->s_name[0] >= '0') && (s->s_name[0] <= '9'))) { x->x_inner_double_value = strtod(s->s_name, &dummy); symtodp_bang(x); } } static void symtodp_list(t_symtodp *x, t_symbol *s, int ac, t_atom *av) { if(ac > 0) { x->x_inner_double_value = symtodp_calc_list_sum(ac, av); // post("listtodp double: %.18g", x->x_inner_double_value); symtodp_bang(x); } } static void symtodp_anything(t_symtodp *x, t_symbol *s, int ac, t_atom *av) { char *dummy; if((s->s_name[0] == '"') && (s->s_name[1])) { if((s->s_name[1] == '.') || (s->s_name[1] == '+') || (s->s_name[1] == '-') || ((s->s_name[1] >= '0') && (s->s_name[1] <= '9'))) { x->x_inner_double_value = strtod(s->s_name+1, &dummy); symtodp_bang(x); } } } static void *symtodp_new(void) { t_symtodp *x = (t_symtodp *)pd_new(symtodp_class); x->x_inner_double_value = 0.0; x->x_out_floatcasted = outlet_new(&x->x_obj, &s_float); x->x_out_residual = outlet_new(&x->x_obj, &s_float); return (x); } static void symtodp_free(t_symtodp *x) { } void symtodp_setup(void) { symtodp_class = class_new(gensym("symtodp"), (t_newmethod)symtodp_new, (t_method)symtodp_free, sizeof(t_symtodp), 0, 0); class_addbang(symtodp_class, symtodp_bang); class_addfloat(symtodp_class, symtodp_float); class_addsymbol(symtodp_class, symtodp_symbol); class_addlist(symtodp_class, symtodp_list); class_addanything(symtodp_class, symtodp_anything); }