void add_numbers(void) { double a, b; if (isrational(stack[tos - 1]) && isrational(stack[tos - 2])) { qadd(); return; } save(); p2 = pop(); p1 = pop(); if (isdouble(p1)) a = p1->u.d; else a = convert_rational_to_double(p1); if (isdouble(p2)) b = p2->u.d; else b = convert_rational_to_double(p2); push_double(a + b); restore(); }
void divide_numbers(void) { double a, b; if (isrational(stack[tos - 1]) && isrational(stack[tos - 2])) { qdiv(); return; } save(); p2 = pop(); p1 = pop(); if (iszero(p2)) stop("divide by zero"); if (isdouble(p1)) a = p1->u.d; else a = convert_rational_to_double(p1); if (isdouble(p2)) b = p2->u.d; else b = convert_rational_to_double(p2); push_double(a / b); restore(); }
bool isNumber(const char *s) { int e = -1; while (*s == ' ') s++; if (*s == '+' || *s == '-'){ s++; } int n = strlen(s); while (n>0 && s[n-1] == ' ') n--; for (int i = 0; i<n; i++) if (s[i] == 'e'){ e = i; break; } if (e == -1){ return isdouble(s, n); } if (!isdouble(s, e)) return false; s += e+1; n-=e+1; if (*s == '+' || *s == '-'){ s++; n--; } return isInt(s, n); }
/* Callback called when a mouse button is pressed or released - b : mouse button identifier [IUP_BUTTON1, IUP_BUTTON2 or IUP_BUTTON3] - press : 1 if the button has been pressed 0, if it has been released - x, y : mouse position - r : string containing which keys [SHIFT, CTRL and ALT] are pressed */ int iupTreeMouseButtonCB(Ihandle* ih, int b, int press, int x, int y, char* r) { if(press) { /* The edit Kill Focus is not called when the user clicks in the parent canvas. So we have to compensate that. */ iupTreeEditCheckHidden(ih); } if(b == IUP_BUTTON1) { if(!press && tree_drag) { int control = 0; int shift = 0; if(ih->data->tree_ctrl == YES) control = iscontrol(r); if(ih->data->tree_shift == YES) shift = isshift(r); iTreeMouseDrop(ih, x, y, shift, control); } if((!press || isdouble(r)) && !tree_drag) { int dclick = isdouble(r); int control = 0; int shift = 0; if(ih->data->tree_ctrl == YES) control = iscontrol(r); if(ih->data->tree_shift == YES) shift = isshift(r); iTreeMouseLeftPress(ih, x, y, shift, control, dclick); } if(press && !isdouble(r)) { if(iupAttribGetInt(ih, "SHOWDRAGDROP")) iTreeMouseDrag(ih, x, y); } } if(b == IUP_BUTTON3) { if(!press) { iTreeMouseRightPress(ih, x, y, r); } } return IUP_DEFAULT; }
void arctanh(void) { double d; save(); p1 = pop(); if (car(p1) == symbol(TANH)) { push(cadr(p1)); restore(); return; } if (isdouble(p1)) { d = p1->u.d; if (d < -1.0 || d > 1.0) stop("arctanh function argument is not in the interval [-1,1]"); d = log((1.0 + d) / (1.0 - d)) / 2.0; push_double(d); restore(); return; } if (iszero(p1)) { push(zero); restore(); return; } push_symbol(ARCTANH); push(p1); list(2); restore(); }
void arccosh(void) { double d; save(); p1 = pop(); if (car(p1) == symbol(COSH)) { push(cadr(p1)); restore(); return; } if (isdouble(p1)) { d = p1->u.d; if (d < 1.0) stop("arccosh function argument is less than 1.0"); d = log(d + sqrt(d * d - 1.0)); push_double(d); restore(); return; } if (isplusone(p1)) { push(zero); restore(); return; } push_symbol(ARCCOSH); push(p1); list(2); restore(); }
int check_var_double(char * s, int l) { int i,p=1; for(i=0;i<l;i++) p=p&&(isdouble(s[i]))&&(i==0||s[i]!='-'); return p; }
void invert_number(void) { unsigned int *a, *b; save(); p1 = pop(); if (iszero(p1)) stop("divide by zero"); if (isdouble(p1)) { push_double(1 / p1->u.d); restore(); return; } a = mcopy(p1->u.q.a); b = mcopy(p1->u.q.b); MSIGN(b) = MSIGN(a); MSIGN(a) = 1; p1 = alloc(); p1->k = NUM; p1->u.q.a = b; p1->u.q.b = a; push(p1); restore(); }
static void yyerf(void) { double d; p1 = pop(); if (isdouble(p1)) { d = 1.0 - erfc(p1->u.d); push_double(d); return; } if (isnegativeterm(p1)) { push_symbol(ERF); push(p1); negate(); list(2); negate(); return; } push_symbol(ERF); push(p1); list(2); return; }
void arcsinh(void) { double d; save(); p1 = pop(); if (car(p1) == symbol(SINH)) { push(cadr(p1)); restore(); return; } if (isdouble(p1)) { d = p1->u.d; d = log(d + sqrt(d * d + 1.0)); push_double(d); restore(); return; } if (iszero(p1)) { push(zero); restore(); return; } push_symbol(ARCSINH); push(p1); list(2); restore(); }
int check_var_array(char * s, int l) { int i,p=1,count=0; for(i=0;i<l;i++) { if(s[i]==':') count++; p=p&&(isdouble(s[i])||s[i]==':'); } return (p&&count>=1&&count<=2)?count:0; }
int compare_numbers(U *a, U *b) { double x, y; if (isrational(a) && isrational(b)) return compare_rationals(a, b); if (isdouble(a)) x = a->u.d; else x = convert_rational_to_double(a); if (isdouble(b)) y = b->u.d; else y = convert_rational_to_double(b); if (x < y) return -1; if (x > y) return 1; return 0; }
void get_operand(const char *str, Testable *f, uint32 *word0, uint32 *word1) { struct special { unsigned dblword0, dblword1, sglword; const char *name; } specials[] = { {0x00000000,0x00000000,0x00000000,"0"}, {0x3FF00000,0x00000000,0x3f800000,"1"}, {0x7FF00000,0x00000000,0x7f800000,"inf"}, {0x7FF80000,0x00000001,0x7fc00000,"qnan"}, {0x7FF00000,0x00000001,0x7f800001,"snan"}, {0x3ff921fb,0x54442d18,0x3fc90fdb,"pi2"}, {0x400921fb,0x54442d18,0x40490fdb,"pi"}, {0x3fe921fb,0x54442d18,0x3f490fdb,"pi4"}, {0x4002d97c,0x7f3321d2,0x4016cbe4,"3pi4"}, }; int i; for (i = 0; i < (int)(sizeof(specials)/sizeof(*specials)); i++) { if (!strcmp(str, specials[i].name) || ((str[0] == '-' || str[0] == '+') && !strcmp(str+1, specials[i].name))) { assert(f); if (isdouble(f)) { *word0 = specials[i].dblword0; *word1 = specials[i].dblword1; } else { *word0 = specials[i].sglword; *word1 = 0; } if (str[0] == '-') *word0 |= 0x80000000U; return; } } sscanf(str, "%"I32"x.%"I32"x", word0, word1); }
void yybessely(void) { double d; int n; N = pop(); X = pop(); push(N); n = pop_integer(); if (isdouble(X) && n != (int) 0x80000000) { d = yn(n, X->u.d); push_double(d); return; } if (isnegativeterm(N)) { push_integer(-1); push(N); power(); push_symbol(BESSELY); push(X); push(N); negate(); list(3); multiply(); return; } push_symbol(BESSELY); push(X); push(N); list(3); return; }
void yyfloor(void) { double d; p1 = pop(); if (!isnum(p1)) { push_symbol(FLOOR); push(p1); list(2); return; } if (isdouble(p1)) { d = floor(p1->u.d); push_double(d); return; } if (isinteger(p1)) { push(p1); return; } p3 = alloc(); p3->k = NUM; p3->u.q.a = mdiv(p1->u.q.a, p1->u.q.b); p3->u.q.b = mint(1); push(p3); if (isnegativenumber(p1)) { push_integer(-1); add(); } }
void yysinh(void) { double d; p1 = pop(); if (car(p1) == symbol(ARCSINH)) { push(cadr(p1)); return; } if (isdouble(p1)) { d = sinh(p1->u.d); if (fabs(d) < 1e-10) d = 0.0; push_double(d); return; } if (iszero(p1)) { push(zero); return; } push_symbol(SINH); push(p1); list(2); }
void arctan(void) { double d; save(); p1 = pop(); if (car(p1) == symbol(TAN)) { push(cadr(p1)); restore(); return; } if (isdouble(p1)) { errno = 0; d = atan(p1->u.d); if (errno) stop("arctan function error"); push_double(d); restore(); return; } if (iszero(p1)) { push(zero); restore(); return; } if (isnegative(p1)) { push(p1); negate(); arctan(); negate(); restore(); return; } // arctan(sin(a) / cos(a)) ? if (find(p1, symbol(SIN)) && find(p1, symbol(COS))) { push(p1); numerator(); p2 = pop(); push(p1); denominator(); p3 = pop(); if (car(p2) == symbol(SIN) && car(p3) == symbol(COS) && equal(cadr(p2), cadr(p3))) { push(cadr(p2)); restore(); return; } } // arctan(1/sqrt(3)) -> pi/6 if (car(p1) == symbol(POWER) && equaln(cadr(p1), 3) && equalq(caddr(p1), -1, 2)) { push_rational(1, 6); push(symbol(PI)); multiply(); restore(); return; } // arctan(1) -> pi/4 if (equaln(p1, 1)) { push_rational(1, 4); push(symbol(PI)); multiply(); restore(); return; } // arctan(sqrt(3)) -> pi/3 if (car(p1) == symbol(POWER) && equaln(cadr(p1), 3) && equalq(caddr(p1), 1, 2)) { push_rational(1, 3); push(symbol(PI)); multiply(); restore(); return; } push_symbol(ARCTAN); push(p1); list(2); restore(); }
void cosine_of_angle(void) { int n; double d; if (car(p1) == symbol(ARCCOS)) { push(cadr(p1)); return; } if (isdouble(p1)) { d = cos(p1->u.d); if (fabs(d) < 1e-10) d = 0.0; push_double(d); return; } // cosine function is symmetric, cos(-x) = cos(x) if (isnegative(p1)) { push(p1); negate(); p1 = pop(); } // cos(arctan(x)) = 1 / sqrt(1 + x^2) // see p. 173 of the CRC Handbook of Mathematical Sciences if (car(p1) == symbol(ARCTAN)) { push_integer(1); push(cadr(p1)); push_integer(2); power(); add(); push_rational(-1, 2); power(); return; } // multiply by 180/pi push(p1); push_integer(180); multiply(); push_symbol(PI); divide(); n = pop_integer(); if (n < 0) { push(symbol(COS)); push(p1); list(2); return; } switch (n % 360) { case 90: case 270: push_integer(0); break; case 60: case 300: push_rational(1, 2); break; case 120: case 240: push_rational(-1, 2); break; case 45: case 315: push_rational(1, 2); push_integer(2); push_rational(1, 2); power(); multiply(); break; case 135: case 225: push_rational(-1, 2); push_integer(2); push_rational(1, 2); power(); multiply(); break; case 30: case 330: push_rational(1, 2); push_integer(3); push_rational(1, 2); power(); multiply(); break; case 150: case 210: push_rational(-1, 2); push_integer(3); push_rational(1, 2); power(); multiply(); break; case 0: push_integer(1); break; case 180: push_integer(-1); break; default: push(symbol(COS)); push(p1); list(2); break; } }
void yypower(void) { int n; p2 = pop(); p1 = pop(); // both base and exponent are rational numbers? if (isrational(p1) && isrational(p2)) { push(p1); push(p2); qpow(); return; } // both base and exponent are either rational or double? if (isnum(p1) && isnum(p2)) { push(p1); push(p2); dpow(); return; } if (istensor(p1)) { power_tensor(); return; } if (p1 == symbol(E) && car(p2) == symbol(LOG)) { push(cadr(p2)); return; } if (p1 == symbol(E) && isdouble(p2)) { push_double(exp(p2->u.d)); return; } // 1 ^ a -> 1 // a ^ 0 -> 1 if (equal(p1, one) || iszero(p2)) { push(one); return; } // a ^ 1 -> a if (equal(p2, one)) { push(p1); return; } // (a * b) ^ c -> (a ^ c) * (b ^ c) if (car(p1) == symbol(MULTIPLY)) { p1 = cdr(p1); push(car(p1)); push(p2); power(); p1 = cdr(p1); while (iscons(p1)) { push(car(p1)); push(p2); power(); multiply(); p1 = cdr(p1); } return; } // (a ^ b) ^ c -> a ^ (b * c) if (car(p1) == symbol(POWER)) { push(cadr(p1)); push(caddr(p1)); push(p2); multiply(); power(); return; } // (a + b) ^ n -> (a + b) * (a + b) ... if (expanding && isadd(p1) && isnum(p2)) { push(p2); n = pop_integer(); // this && n != 0x80000000 added by DDC // as it's not always the case that 0x80000000 // is negative if (n > 1 && n != 0x80000000) { power_sum(n); return; } } // sin(x) ^ 2n -> (1 - cos(x) ^ 2) ^ n if (trigmode == 1 && car(p1) == symbol(SIN) && iseveninteger(p2)) { push_integer(1); push(cadr(p1)); cosine(); push_integer(2); power(); subtract(); push(p2); push_rational(1, 2); multiply(); power(); return; } // cos(x) ^ 2n -> (1 - sin(x) ^ 2) ^ n if (trigmode == 2 && car(p1) == symbol(COS) && iseveninteger(p2)) { push_integer(1); push(cadr(p1)); sine(); push_integer(2); power(); subtract(); push(p2); push_rational(1, 2); multiply(); power(); return; } // complex number? (just number, not expression) if (iscomplexnumber(p1)) { // integer power? // n will be negative here, positive n already handled if (isinteger(p2)) { // / \ n // -n | a - ib | // (a + ib) = | -------- | // | 2 2 | // \ a + b / push(p1); conjugate(); p3 = pop(); push(p3); push(p3); push(p1); multiply(); divide(); push(p2); negate(); power(); return; } // noninteger or floating power? if (isnum(p2)) { #if 1 // use polar form push(p1); mag(); push(p2); power(); push_integer(-1); push(p1); arg(); push(p2); multiply(); push(symbol(PI)); divide(); power(); multiply(); #else // use exponential form push(p1); mag(); push(p2); power(); push(symbol(E)); push(p1); arg(); push(p2); multiply(); push(imaginaryunit); multiply(); power(); multiply(); #endif return; } } if (simplify_polar()) return; push_symbol(POWER); push(p1); push(p2); list(3); }
void yybesselj(void) { double d; int n; N = pop(); X = pop(); push(N); n = pop_integer(); // numerical result if (isdouble(X) && n != (int) 0x80000000) { //d = jn(n, X->u.d); push_double(d); return; } // bessej(0,0) = 1 if (iszero(X) && iszero(N)) { push_integer(1); return; } // besselj(0,n) = 0 if (iszero(X) && n != (int) 0x80000000) { push_integer(0); return; } // half arguments if (N->k == NUM && MEQUAL(N->u.q.b, 2)) { // n = 1/2 if (MEQUAL(N->u.q.a, 1)) { push_integer(2); push_symbol(PI); divide(); push(X); divide(); push_rational(1, 2); power(); push(X); sine(); multiply(); return; } // n = -1/2 if (MEQUAL(N->u.q.a, -1)) { push_integer(2); push_symbol(PI); divide(); push(X); divide(); push_rational(1, 2); power(); push(X); cosine(); multiply(); return; } // besselj(x,n) = (2/x) (n-sgn(n)) besselj(x,n-sgn(n)) - besselj(x,n-2*sgn(n)) push_integer(MSIGN(N->u.q.a)); SGN = pop(); push_integer(2); push(X); divide(); push(N); push(SGN); subtract(); multiply(); push(X); push(N); push(SGN); subtract(); besselj(); multiply(); push(X); push(N); push_integer(2); push(SGN); multiply(); subtract(); besselj(); subtract(); return; } push(symbol(BESSELJ)); push(X); push(N); list(3); }
void eval_nroots(void) { volatile int h, i, k, n; push(cadr(p1)); eval(); push(caddr(p1)); eval(); p2 = pop(); if (p2 == symbol(NIL)) guess(); else push(p2); p2 = pop(); p1 = pop(); if (!ispoly(p1, p2)) stop("nroots: polynomial?"); // mark the stack h = tos; // get the coefficients push(p1); push(p2); n = coeff(); if (n > YMAX) stop("nroots: degree?"); // convert the coefficients to real and imaginary doubles for (i = 0; i < n; i++) { push(stack[h + i]); real(); yyfloat(); eval(); p1 = pop(); push(stack[h + i]); imag(); yyfloat(); eval(); p2 = pop(); if (!isdouble(p1) || !isdouble(p2)) stop("nroots: coefficients?"); c[i].r = p1->u.d; c[i].i = p2->u.d; } // pop the coefficients tos = h; // n is the number of coefficients, n = deg(p) + 1 monic(n); for (k = n; k > 1; k--) { findroot(k); if (fabs(a.r) < DELTA) a.r = 0.0; if (fabs(a.i) < DELTA) a.i = 0.0; push_double(a.r); push_double(a.i); push(imaginaryunit); multiply(); add(); divpoly(k); } // now make n equal to the number of roots n = tos - h; if (n > 1) { sort_stack(n); p1 = alloc_tensor(n); p1->u.tensor->ndim = 1; p1->u.tensor->dim[0] = n; for (i = 0; i < n; i++) p1->u.tensor->elem[i] = stack[h + i]; tos = h; push(p1); } }