Advertisement
pablo7890

parser final

Apr 25th, 2013
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 56.34 KB | None | 0 0
  1. #ifndef _MATHEXPR_H
  2. #define _MATHEXPR_H
  3.  
  4. #include<string.h>
  5. #include<stdio.h>
  6. #include<stdlib.h>
  7. #include<math.h>
  8. #include<float.h>
  9. #include <iostream>
  10. #include <iomanip>
  11.  
  12. // Compatibility with long double-typed functions
  13. #define atanl atan
  14. #define asinl asin
  15. #define acosl acos
  16. #define expl exp
  17. #define logl log
  18. #define powl pow
  19. #define pow10l(x) pow(10,x)
  20. #define fabsl fabs
  21. #define cosl cos
  22. #define sinl sin
  23. #define tanl tan
  24. #define fmodl fmod
  25. #define sqrtl sqrt
  26.  
  27. using namespace std;
  28.  
  29. // Warning : if ints are short, everything will fail with strings longer than
  30. // 32767 chars
  31.  
  32.  
  33. const double ErrVal = DBL_MAX;
  34.  
  35. // Class definitions for operations
  36.  
  37. class RVar
  38. {
  39.   public:
  40.     char *name;
  41.     double *pval;
  42.       RVar()
  43.     {
  44.         name = NULL;
  45.         pval = NULL;
  46.     };
  47.     RVar(const RVar &);
  48.     RVar(const char *, double *);
  49.     ~RVar();
  50.     friend int operator==(const RVar &, const RVar &);
  51. };
  52.  
  53. typedef RVar *PRVar;
  54.  
  55. enum ROperator
  56. { ErrOp, Juxt, Num, Var, Add, Sub, Opp, Mult, Div, Pow, Sqrt,
  57.     NthRoot, Abs, Sin, Cos, Tg, Ln, Exp, Acos, Asin, Atan, E10, Fun
  58. };
  59.  
  60. typedef void ((*pfoncld) (double *&));
  61.  
  62. class ROperation;
  63. typedef ROperation *PROperation;
  64. class RFunction;
  65. typedef RFunction *PRFunction;
  66.  
  67. class ROperation
  68. {
  69.     pfoncld *pinstr;
  70.     double **pvals;
  71.     double *ppile;
  72.     RFunction **pfuncpile;
  73.     mutable signed char containfuncflag;
  74.     void BuildCode();
  75.     void Destroy();
  76.   public:
  77.       ROperator op;
  78.     PROperation mmb1, mmb2;
  79.     double ValC;
  80.     const RVar *pvar;
  81.     double *pvarval;
  82.     RFunction *pfunc;
  83.       ROperation();
  84.       ROperation(const ROperation &);
  85.       ROperation(double);
  86.       ROperation(const RVar &);
  87.       ROperation(char *sp, int nvarp = 0, PRVar * ppvarp = NULL, int nfuncp =
  88.                  0, PRFunction * ppfuncp = NULL);
  89.      ~ROperation();
  90.     double Val() const;
  91.     signed char ContainVar(const RVar &) const;
  92.     signed char ContainFunc(const RFunction &) const;
  93.     signed char ContainFuncNoRec(const RFunction &) const;  // No recursive
  94.                                                             // test on
  95.                                                             // subfunctions
  96.     ROperation NthMember(int) const;
  97.     int NMembers() const;
  98.     signed char HasError(const ROperation * = NULL) const;
  99.       ROperation & operator=(const ROperation &);
  100.     friend int operator==(const ROperation &, const double);
  101.     friend int operator==(const ROperation &, const ROperation &);
  102.     friend int operator!=(const ROperation &, const ROperation &);
  103.     ROperation operator+() const;
  104.     ROperation operator-() const;
  105.     friend ROperation operator, (const ROperation &, const ROperation &);
  106.     friend ROperation operator+(const ROperation &, const ROperation &);
  107.     friend ROperation operator-(const ROperation &, const ROperation &);
  108.     friend ROperation operator*(const ROperation &, const ROperation &);
  109.     friend ROperation operator/(const ROperation &, const ROperation &);
  110.     friend ROperation operator^(const ROperation &, const ROperation &);    // Caution:
  111.                                                                             // wrong
  112.                                                                             // associativity
  113.                                                                             // and
  114.                                                                             // precedence
  115.     friend ROperation sqrt(const ROperation &);
  116.     friend ROperation abs(const ROperation &);
  117.     friend ROperation sin(const ROperation &);
  118.     friend ROperation cos(const ROperation &);
  119.     friend ROperation tan(const ROperation &);
  120.     friend ROperation log(const ROperation &);
  121.     friend ROperation exp(const ROperation &);
  122.     friend ROperation acos(const ROperation &);
  123.     friend ROperation asin(const ROperation &);
  124.     friend ROperation atan(const ROperation &);
  125.     friend ROperation ApplyOperator(int, ROperation **,
  126.                                     ROperation(*)(const ROperation &,
  127.                                                   const ROperation &));
  128.     ROperation Diff(const RVar &) const;    // Differentiate w.r.t a variable
  129.     char *Expr() const;
  130.     ROperation Substitute(const RVar &, const ROperation &) const;
  131. };
  132.  
  133. class RFunction
  134. {
  135.     double *buf;
  136.   public:
  137.     signed char type;
  138.     double ((*pfuncval) (double));
  139.     ROperation op;
  140.     int nvars;
  141.     RVar **ppvar;
  142.     char *name;
  143.       RFunction();
  144.       RFunction(double ((*)(double)));
  145.       RFunction(const ROperation & opp, RVar * pvarp);
  146.       RFunction(const ROperation & opp, int nvarsp, RVar ** ppvarp);
  147.       RFunction(const RFunction &);
  148.      ~RFunction();
  149.       RFunction & operator=(const RFunction &);
  150.     void SetName(const char *s);
  151.     double Val(double) const;
  152.     double Val(double *) const;
  153.     friend int operator==(const RFunction &, const RFunction &);
  154.     ROperation operator() (const ROperation &);
  155. };
  156.  
  157.  
  158. char *MidStr(const char *s, int i1, int i2);
  159. char *CopyStr(const char *s);
  160. char *InsStr(const char *s, int n, char c);
  161. signed char EqStr(const char *s, const char *s2);
  162. signed char CompStr(const char *s, int n, const char *s2);
  163. char *DelStr(const char *s, int n);
  164.  
  165. #endif
  166.  
  167. // ///////////////////////
  168. // ///////////////////////
  169.  
  170.  
  171. char *MidStr(const char *s, int i1, int i2)
  172. {
  173.     if (i1 < 0 || i2 >= (int)strlen(s) || i1 > i2)
  174.     {
  175.         char *cp = new char[1];
  176.         cp[0] = '\0';
  177.         return cp;
  178.     }
  179.     char *s1 = new char[i2 - i1 + 2];
  180.     int i;
  181.     for (i = i1; i <= i2; i++)
  182.         s1[i - i1] = s[i];
  183.     s1[i2 - i1 + 1] = 0;
  184.     return s1;
  185. }
  186.  
  187. char *CopyStr(const char *s)
  188. {
  189.     char *s1 = new char[strlen(s) + 1];
  190.     char *s12 = s1;
  191.     const char *s2 = s;
  192.     while ((*s12++ = *s2++));
  193.     return s1;
  194. }
  195.  
  196. void InsStr(char *&s, int n, char c)    // Warning : deletes the old string
  197. {
  198.     if (n < 0 || n > (int)strlen(s))
  199.         return;
  200.     char *s1 = new char[strlen(s) + 2];
  201.     int i;
  202.     for (i = 0; i < n; i++)
  203.         s1[i] = s[i];
  204.     s1[n] = c;
  205.     for (i = n + 1; s[i - 1]; i++)
  206.         s1[i] = s[i - 1];
  207.     s1[i] = 0;
  208.     delete[]s;
  209.     s = s1;
  210. }
  211.  
  212. signed char EqStr(const char *s, const char *s2)
  213. {
  214.     if (strlen(s) != strlen(s2))
  215.         return 0;
  216.     int i;
  217.     for (i = 0; s[i]; i++)
  218.         if (s[i] != s2[i])
  219.             return 0;
  220.     return 1;
  221. }
  222.  
  223. signed char CompStr(const char *s, int n, const char *s2)
  224. {
  225.     if (n < 0 || n >= (int)strlen(s) || n + (int)strlen(s2) > (int)strlen(s))
  226.         return 0;
  227.     int i;
  228.     for (i = 0; s2[i]; i++)
  229.         if (s[i + n] != s2[i])
  230.             return 0;
  231.     return 1;
  232. }
  233.  
  234. void DelStr(char *&s, int n)    // Deletes the old string
  235. {
  236.     char *s1 = new char[strlen(s)];
  237.     int i;
  238.     for (i = 0; i < n; i++)
  239.         s1[i] = s[i];
  240.     for (i = n; s[i + 1]; i++)
  241.         s1[i] = s[i + 1];
  242.     s1[i] = 0;
  243.     delete[]s;
  244.     s = s1;
  245. }
  246.  
  247. RVar::RVar(const RVar & rvarp)
  248. {
  249.     if (this == &rvarp)
  250.         return;
  251.     pval = rvarp.pval;
  252.     name = CopyStr(rvarp.name);
  253. }
  254.  
  255. RVar::RVar(const char *namep, double *pvalp)
  256. {
  257.     pval = pvalp;
  258.     name = CopyStr(namep);
  259. }
  260.  
  261. RVar::~RVar()
  262. {
  263.     if (name != NULL)
  264.         delete[]name;
  265. }
  266.  
  267. RFunction::RFunction()
  268. {
  269.     type = -1;
  270.     name = new char[1];
  271.     name[0] = 0;
  272.     nvars = 0;
  273.     ppvar = NULL;
  274.     pfuncval = NULL;
  275.     op = ErrVal;
  276.     buf = NULL;
  277. }
  278.  
  279. RFunction::RFunction(double ((*pfuncvalp) (double)))
  280. {
  281.     type = 0;
  282.     pfuncval = pfuncvalp;
  283.     name = new char[1];
  284.     name[0] = 0;
  285.     nvars = 1;
  286.     ppvar = NULL;
  287.     op = ErrVal;
  288.     buf = NULL;
  289. }
  290.  
  291. RFunction::RFunction(const RFunction & rfunc)
  292. {
  293.     if (this == &rfunc)
  294.         return;
  295.     type = rfunc.type;
  296.     op = rfunc.op;
  297.     pfuncval = rfunc.pfuncval;
  298.     name = CopyStr(rfunc.name);
  299.     nvars = rfunc.nvars;
  300.     if (rfunc.ppvar != NULL && nvars)
  301.     {
  302.         ppvar = new PRVar[nvars];
  303.         int i;
  304.         for (i = 0; i < nvars; i++)
  305.             ppvar[i] = rfunc.ppvar[i];
  306.         buf = new double[nvars];
  307.     }
  308.     else
  309.     {
  310.         ppvar = NULL;
  311.         buf = NULL;
  312.     }
  313. }
  314.  
  315. RFunction::RFunction(const ROperation & opp, RVar * pvarp):op(opp)
  316. {
  317.     type = 1;
  318.     name = new char[1];
  319.     name[0] = 0;
  320.     nvars = 1;
  321.     ppvar = new PRVar[1];
  322.     ppvar[0] = pvarp;
  323.     buf = new double[1];
  324. }
  325.  
  326. RFunction::RFunction(const ROperation & opp, int nvarsp,
  327.                      RVar ** ppvarp):op(opp)
  328. {
  329.     type = 1;
  330.     name = new char[1];
  331.     name[0] = 0;
  332.     nvars = nvarsp;
  333.     if (nvars)
  334.     {
  335.         ppvar = new PRVar[nvars];
  336.         int i;
  337.         for (i = 0; i < nvars; i++)
  338.             ppvar[i] = ppvarp[i];
  339.         buf = new double[nvars];
  340.     }
  341.     else
  342.     {
  343.         ppvar = NULL;
  344.         buf = NULL;
  345.     }
  346. }
  347.  
  348. RFunction::~RFunction()
  349. {
  350.     if (name != NULL)
  351.         delete[]name;
  352.     if (ppvar != NULL)
  353.         delete[]ppvar;
  354.     if (buf != NULL)
  355.         delete[]buf;
  356. }
  357.  
  358. RFunction & RFunction::operator=(const RFunction & rfunc)
  359. {
  360.     if (this == &rfunc)
  361.         return *this;
  362.     type = rfunc.type;
  363.     op = rfunc.op;
  364.     pfuncval = rfunc.pfuncval;
  365.     delete[]name;
  366.     name = CopyStr(rfunc.name);
  367.     if (ppvar != NULL)
  368.         delete[]ppvar;
  369.     ppvar = NULL;
  370.     if (buf != NULL)
  371.         delete[]buf;
  372.     buf = NULL;
  373.     nvars = rfunc.nvars;
  374.     if (type == 1 && nvars)
  375.     {
  376.         ppvar = new PRVar[nvars];
  377.         buf = new double[nvars];
  378.         int i;
  379.         for (i = 0; i < nvars; i++)
  380.             ppvar[i] = rfunc.ppvar[i];
  381.     }
  382.     return *this;
  383. }
  384.  
  385. void RFunction::SetName(const char *s)
  386. {
  387.     if (name != NULL)
  388.         delete[]name;
  389.     name = CopyStr(s);
  390. }
  391.  
  392. double RFunction::Val(double x) const const
  393. {
  394.     if (type == -1 || nvars >= 2)
  395.         return ErrVal;
  396.     if (type == 0)
  397.         return (*pfuncval) (x);
  398.     double xb = *(*ppvar)->pval, y;
  399.     *(*ppvar)->pval = x;        // Warning : could cause trouble if this value
  400.                                 // is used in a parallel process
  401.     y = op.Val();
  402.     *(*ppvar)->pval = xb;
  403.     return y;
  404. }
  405.  
  406. double RFunction::Val(double *pv) const const
  407. {
  408.     if (type == -1)
  409.         return ErrVal;
  410.     if (type == 0)
  411.         return (*pfuncval) (*pv);
  412.     double y;
  413.     int i;
  414.     for (i = 0; i < nvars; i++)
  415.     {
  416.         buf[i] = *ppvar[i]->pval;
  417.         // Warning : could cause trouble if this value is used in a parallel
  418.         // process
  419.         *ppvar[i]->pval = pv[i];
  420.     }
  421.     y = op.Val();
  422.     for (i = 0; i < nvars; i++)
  423.         *ppvar[i]->pval = buf[i];
  424.     return y;
  425. }
  426.  
  427. ROperation::ROperation()
  428. {
  429.     op = ErrOp;
  430.     mmb1 = NULL;
  431.     mmb2 = NULL;
  432.     ValC = ErrVal;
  433.     pvar = NULL;
  434.     pvarval = NULL;
  435.     pfunc = NULL;
  436.     containfuncflag = 0;
  437.     pinstr = NULL;
  438.     pvals = NULL;
  439.     ppile = NULL;
  440.     pfuncpile = NULL;
  441.     BuildCode();
  442. }
  443.  
  444. ROperation::~ROperation()
  445. {
  446.     Destroy();
  447. }
  448.  
  449. ROperation::ROperation(const ROperation & ROp)
  450. {
  451.     op = ROp.op;
  452.     pvar = ROp.pvar;
  453.     pvarval = ROp.pvarval;
  454.     ValC = ROp.ValC;
  455.     pfunc = ROp.pfunc;
  456.     containfuncflag = 0;
  457.     pinstr = NULL;
  458.     pvals = NULL;
  459.     ppile = NULL;
  460.     pfuncpile = NULL;
  461.     if (ROp.mmb1 != NULL)
  462.         mmb1 = new ROperation(*(ROp.mmb1));
  463.     else
  464.         mmb1 = NULL;
  465.     if (ROp.mmb2 != NULL)
  466.         mmb2 = new ROperation(*(ROp.mmb2));
  467.     else
  468.         mmb2 = NULL;
  469.     BuildCode();
  470. }
  471.  
  472. ROperation::ROperation(double x)
  473. {
  474.     if (x == ErrVal)
  475.     {
  476.         op = ErrOp;
  477.         mmb1 = NULL;
  478.         mmb2 = NULL;
  479.         ValC = ErrVal;
  480.     }
  481.     else if (x >= 0)
  482.     {
  483.         op = Num;
  484.         mmb1 = NULL;
  485.         mmb2 = NULL;
  486.         ValC = x;
  487.     }
  488.     else
  489.     {
  490.         op = Opp;
  491.         mmb1 = NULL;
  492.         mmb2 = new ROperation(-x);
  493.         ValC = ErrVal;
  494.     }
  495.     pvar = NULL;
  496.     pvarval = NULL;
  497.     pfunc = NULL;
  498.     containfuncflag = 0;
  499.     pinstr = NULL;
  500.     pvals = NULL;
  501.     ppile = NULL;
  502.     pfuncpile = NULL;
  503.     BuildCode();
  504. }
  505.  
  506. ROperation::ROperation(const RVar & varp)
  507. {
  508.     op = Var;
  509.     mmb1 = NULL;
  510.     mmb2 = NULL;
  511.     ValC = ErrVal;
  512.     pvar = &varp;
  513.     pvarval = varp.pval;
  514.     containfuncflag = 0;
  515.     pfunc = NULL;
  516.     pinstr = NULL;
  517.     pvals = NULL;
  518.     ppile = NULL;
  519.     pfuncpile = NULL;
  520.     BuildCode();
  521. }
  522.  
  523. ROperation & ROperation::operator=(const ROperation & ROp)
  524. {
  525.     if (this == &ROp)
  526.         return *this;
  527.     Destroy();
  528.     op = ROp.op;
  529.     pvar = ROp.pvar;
  530.     pvarval = ROp.pvarval;
  531.     ValC = ROp.ValC;
  532.     pfunc = ROp.pfunc;
  533.     containfuncflag = 0;
  534.     pinstr = NULL;
  535.     pvals = NULL;
  536.     ppile = NULL;
  537.     pfuncpile = NULL;
  538.     if (ROp.mmb1 != NULL)
  539.         mmb1 = new ROperation(*(ROp.mmb1));
  540.     else
  541.         mmb1 = NULL;
  542.     if (ROp.mmb2 != NULL)
  543.         mmb2 = new ROperation(*(ROp.mmb2));
  544.     else
  545.         mmb2 = NULL;
  546.     BuildCode();
  547.     return *this;
  548. }
  549.  
  550. int operator==(const ROperation & op, const double v)
  551. {
  552.     return (op.op == Num && op.ValC == v);
  553. }
  554.  
  555. int operator==(const ROperation & op1, const ROperation & op2)
  556. {
  557.     if (op1.op != op2.op)
  558.         return 0;
  559.     if (op1.op == Var)
  560.         return (*(op1.pvar) == *(op2.pvar));
  561.     if (op1.op == Fun)
  562.         return (op1.pfunc == op2.pfunc);    // *op1.pfunc==*op2.pfunc could
  563.                                             // imply infinite loops in cases
  564.                                             // of self-dependence
  565.     if (op1.op == Num)
  566.         return (op1.ValC == op2.ValC);
  567.     if (op1.mmb1 == NULL && op2.mmb1 != NULL)
  568.         return 0;
  569.     if (op1.mmb2 == NULL && op2.mmb2 != NULL)
  570.         return 0;
  571.     if (op2.mmb1 == NULL && op1.mmb1 != NULL)
  572.         return 0;
  573.     if (op2.mmb2 == NULL && op1.mmb2 != NULL)
  574.         return 0;
  575.     return (((op1.mmb1 == NULL && op2.mmb1 == NULL)
  576.              || (*(op1.mmb1) == *(op2.mmb1))) && ((op1.mmb2 == NULL
  577.                                                    && op2.mmb2 == NULL)
  578.                                                   || (*(op1.mmb2) ==
  579.                                                       *(op2.mmb2))));
  580. }
  581.  
  582. int operator!=(const ROperation & op1, const ROperation & op2)
  583. {
  584.     if (op1.op != op2.op)
  585.         return 1;
  586.     if (op1.op == Var)
  587.         return (op1.pvar != op2.pvar);
  588.     if (op1.op == Fun)
  589.         return (!(op1.pfunc == op2.pfunc)); // *op1.pfunc==*op2.pfunc could
  590.                                             // imply infinite loops in cases
  591.                                             // of self-dependence
  592.     if (op1.op == Num)
  593.         return (op1.ValC != op2.ValC);
  594.     if (op1.mmb1 == NULL && op2.mmb1 != NULL)
  595.         return 1;
  596.     if (op1.mmb2 == NULL && op2.mmb2 != NULL)
  597.         return 1;
  598.     if (op2.mmb1 == NULL && op1.mmb1 != NULL)
  599.         return 1;
  600.     if (op2.mmb2 == NULL && op1.mmb2 != NULL)
  601.         return 1;
  602.     return (((op1.mmb1 != NULL || op2.mmb1 != NULL)
  603.              && (*(op1.mmb1) != *(op2.mmb1))) || ((op1.mmb2 != NULL
  604.                                                    || op2.mmb2 != NULL)
  605.                                                   && (*(op1.mmb2) !=
  606.                                                       *(op2.mmb2))));
  607. }
  608.  
  609. ROperation ROperation::operator+() const const
  610. {
  611.     return *this;
  612. }
  613.  
  614. ROperation ROperation::operator-() const const
  615. {
  616.     if (op == Num)
  617.         return -ValC;
  618.     ROperation resultat;
  619.     if (op == Opp)
  620.         resultat = *mmb2;
  621.     else
  622.     {
  623.         resultat.op = Opp;
  624.         resultat.mmb2 = new ROperation(*this);
  625.     };
  626.     return resultat;
  627. }
  628.  
  629. ROperation operator, (const ROperation & op1, const ROperation & op2)
  630. {
  631.     ROperation resultat;
  632.     resultat.op = Juxt;
  633.     resultat.mmb1 = new ROperation(op1);
  634.     resultat.mmb2 = new ROperation(op2);
  635.     return resultat;
  636. }
  637.  
  638. ROperation operator+(const ROperation & op1, const ROperation & op2)
  639. {
  640.     if (op1.op == Num && op2.op == Num)
  641.         return op1.ValC + op2.ValC;
  642.     if (op1 == 0.)
  643.         return op2;
  644.     if (op2 == 0.)
  645.         return op1;
  646.     if (op1.op == Opp)
  647.         return op2 - *(op1.mmb2);
  648.     if (op2.op == Opp)
  649.         return op1 - *(op2.mmb2);
  650.     ROperation resultat;
  651.     resultat.op = Add;
  652.     resultat.mmb1 = new ROperation(op1);
  653.     resultat.mmb2 = new ROperation(op2);
  654.     return resultat;
  655. }
  656.  
  657. ROperation operator-(const ROperation & op1, const ROperation & op2)
  658. {
  659.     if (op1.op == Num && op2.op == Num)
  660.         return op1.ValC - op2.ValC;
  661.     if (op1 == 0.)
  662.         return -op2;
  663.     if (op2 == 0.)
  664.         return op1;
  665.     if (op1.op == Opp)
  666.         return -(op2 + *(op1.mmb2));
  667.     if (op2.op == Opp)
  668.         return op1 + *(op2.mmb2);
  669.     ROperation resultat;
  670.     resultat.op = Sub;
  671.     resultat.mmb1 = new ROperation(op1);
  672.     resultat.mmb2 = new ROperation(op2);
  673.     return resultat;
  674. }
  675.  
  676. ROperation operator*(const ROperation & op1, const ROperation & op2)
  677. {
  678.     if (op1.op == Num && op2.op == Num)
  679.         return op1.ValC * op2.ValC;
  680.     if (op1 == 0. || op2 == 0.)
  681.         return 0.;
  682.     if (op1 == 1.)
  683.         return op2;
  684.     if (op2 == 1.)
  685.         return op1;
  686.     if (op1.op == Opp)
  687.         return -(*(op1.mmb2) * op2);
  688.     if (op2.op == Opp)
  689.         return -(op1 ** (op2.mmb2));
  690.     ROperation resultat;
  691.     resultat.op = Mult;
  692.     resultat.mmb1 = new ROperation(op1);
  693.     resultat.mmb2 = new ROperation(op2);
  694.     return resultat;
  695. }
  696.  
  697. ROperation operator/(const ROperation & op1, const ROperation & op2)
  698. {
  699.     if (op1.op == Num && op2.op == Num)
  700.         return (op2.ValC ? op1.ValC / op2.ValC : ErrVal);
  701.     if (op1 == 0.0)
  702.         return 0.;
  703.     if (op2 == 1.)
  704.         return op1;
  705.     if (op2 == 0.)
  706.         return ErrVal;
  707.     if (op1.op == Opp)
  708.         return -(*(op1.mmb2) / op2);
  709.     if (op2.op == Opp)
  710.         return -(op1 / (*(op2.mmb2)));
  711.     ROperation resultat;
  712.     resultat.op = Div;
  713.     resultat.mmb1 = new ROperation(op1);
  714.     resultat.mmb2 = new ROperation(op2);
  715.     return resultat;
  716. }
  717.  
  718. ROperation operator^(const ROperation & op1, const ROperation & op2)
  719. {
  720.     if (op1 == 0.)
  721.         return 0.;
  722.     if (op2 == 0.)
  723.         return 1.;
  724.     if (op2 == 1.)
  725.         return op1;
  726.     ROperation resultat;
  727.     resultat.op = Pow;
  728.     resultat.mmb1 = new ROperation(op1);
  729.     resultat.mmb2 = new ROperation(op2);
  730.     return resultat;
  731. }
  732.  
  733. ROperation sqrt(const ROperation & op)
  734. {
  735.     ROperation rop;
  736.     rop.op = Sqrt;
  737.     rop.mmb2 = new ROperation(op);
  738.     return rop;
  739. }
  740.  
  741. ROperation abs(const ROperation & op)
  742. {
  743.     ROperation rop;
  744.     rop.op = Abs;
  745.     rop.mmb2 = new ROperation(op);
  746.     return rop;
  747. }
  748.  
  749. ROperation sin(const ROperation & op)
  750. {
  751.     ROperation rop;
  752.     rop.op = Sin;
  753.     rop.mmb2 = new ROperation(op);
  754.     return rop;
  755. }
  756.  
  757. ROperation cos(const ROperation & op)
  758. {
  759.     ROperation rop;
  760.     rop.op = Cos;
  761.     rop.mmb2 = new ROperation(op);
  762.     return rop;
  763. }
  764.  
  765. ROperation tan(const ROperation & op)
  766. {
  767.     ROperation rop;
  768.     rop.op = Tg;
  769.     rop.mmb2 = new ROperation(op);
  770.     return rop;
  771. }
  772.  
  773. ROperation log(const ROperation & op)
  774. {
  775.     ROperation rop;
  776.     rop.op = Ln;
  777.     rop.mmb2 = new ROperation(op);
  778.     return rop;
  779. }
  780.  
  781. ROperation exp(const ROperation & op)
  782. {
  783.     ROperation rop;
  784.     rop.op = Exp;
  785.     rop.mmb2 = new ROperation(op);
  786.     return rop;
  787. }
  788.  
  789. ROperation acos(const ROperation & op)
  790. {
  791.     ROperation rop;
  792.     rop.op = Acos;
  793.     rop.mmb2 = new ROperation(op);
  794.     return rop;
  795. }
  796.  
  797. ROperation asin(const ROperation & op)
  798. {
  799.     ROperation rop;
  800.     rop.op = Asin;
  801.     rop.mmb2 = new ROperation(op);
  802.     return rop;
  803. }
  804.  
  805. ROperation atan(const ROperation & op)
  806. {
  807.     ROperation rop;
  808.     rop.op = Atan;
  809.     rop.mmb2 = new ROperation(op);
  810.     return rop;
  811. }
  812.  
  813. ROperation ApplyOperator(int n, ROperation ** pops,
  814.                          ROperation(*func) (const ROperation &,
  815.                                             const ROperation &))
  816. {
  817.     if (n <= 0)
  818.         return ErrVal;
  819.     if (n == 1)
  820.         return *pops[0];
  821.     if (n == 2)
  822.         return (*func) (*pops[0], *pops[1]);
  823.     return (*func) (*pops[0], ApplyOperator(n - 1, pops + 1, func));
  824. }
  825.  
  826. ROperation RFunction::operator() (const ROperation & op)
  827. {
  828.     /* Code to use to replace explcitly instead of using a pointer to
  829.        if(nvars!=op.NMembers()||type==-1||type==0)return ErrVal; ROperation
  830.        op2=*pop;int i; RVar**ppvar2=new PRVar[nvars];char s[11]="";
  831.        for(i=0;i<nvars;i++){ sprintf(s,";var%i;",i); ppvar2[i]=new
  832.        RVar(s,NULL); op2=op2.Substitute(*ppvar[i],(ROperation)*ppvar2[i]); }
  833.        for(i=0;i<nvars;i++){ op2=op2.Substitute(*ppvar2[i],op.NthMember(i+1));
  834.        delete ppvar2[i]; } delete[]ppvar2; return op2; */
  835.     ROperation op2;
  836.     op2.op = Fun;
  837.     op2.pfunc = this;
  838.     op2.mmb2 = new ROperation(op);
  839.     return op2;
  840. }
  841.  
  842. // Auxiliary string functions
  843.  
  844. void SupprSpaces(char *&s)      // Deletes the old string
  845. {
  846.     int i;
  847.     for (i = 0; s[i]; i++)
  848.         if (s[i] == ' ' || s[i] == '\t' || s[i] == '\n')
  849.             DelStr(s, i--);
  850. }
  851.  
  852. signed char IsNumeric(char c)
  853. {
  854.     if (c != '0' && c != '1' && c != '2' && c != '3' && c != '4'
  855.         && c != '5' && c != '6' && c != '7' && c != '8' && c != '9'
  856.         && c != '.')
  857.         return 0;
  858.     return 1;
  859. }
  860.  
  861. signed char IsTNumeric(char *s)
  862. {
  863.     int i;
  864.     for (i = 0; i < (int)strlen(s); i++)
  865.         if (!IsNumeric(s[i]))
  866.             return 0;
  867.     return 1;
  868. }
  869.  
  870. int SearchCorOpenbracket(char *s, int n)    // Searchs the corresponding
  871.                                             // bracket of an opening bracket
  872. {
  873.     if (n >= (int)strlen(s) - 1)
  874.         return -1;
  875.     int i, c = 1;
  876.     for (i = n + 1; s[i]; i++)
  877.     {
  878.         if (s[i] == '(')
  879.             c++;
  880.         else if (s[i] == ')')
  881.             c--;
  882.         if (!c)
  883.             return i;
  884.     };
  885.     return -1;
  886. }
  887.  
  888. int SearchCorClosebracket(char *s, int n)   // Searchs the corresponding
  889.                                             // bracket of a closing bracket
  890. {
  891.     if (n < 1)
  892.         return -1;
  893.     int i, c = 1;
  894.     for (i = n - 1; i >= 0; i--)
  895.     {
  896.         if (s[i] == ')')
  897.             c++;
  898.         else if (s[i] == '(')
  899.             c--;
  900.         if (!c)
  901.             return i;
  902.     };
  903.     return -1;
  904. }
  905.  
  906. int SearchOperator(char *s, ROperator op)
  907. {
  908.     char opc;
  909.     switch (op)
  910.     {
  911.     case ErrOp:
  912.     case Num:
  913.     case Var:
  914.         return -1;
  915.     case Juxt:
  916.         opc = ',';
  917.         break;
  918.     case Add:
  919.         opc = '+';
  920.         break;
  921.     case Sub:
  922.         opc = '-';
  923.         break;
  924.     case Mult:
  925.         opc = '*';
  926.         break;
  927.     case Div:
  928.         opc = '/';
  929.         break;
  930.     case Pow:
  931.         opc = '^';
  932.         break;
  933.     case NthRoot:
  934.         opc = '#';
  935.         break;
  936.     case E10:
  937.         opc = 'E';
  938.         break;
  939.     default:
  940.         return -1;
  941.     };
  942.     int i;
  943.     for (i = (int)strlen(s) - 1; i >= 0; i--)
  944.     {
  945.         if (s[i] == opc && (op != Sub || i && s[i - 1] == ')'))
  946.             return i;
  947.         if (s[i] == ')')
  948.         {
  949.             i = SearchCorClosebracket(s, i);
  950.             if (i == -1)
  951.                 return -1;
  952.         };
  953.     };
  954.     return -1;
  955. }
  956.  
  957. void SimplifyStr(char *&s)      // Warning : deletes the old string
  958. {
  959.     if (!strlen(s))
  960.         return;
  961.     char *s1 = s, *s2 = s + strlen(s);
  962.     signed char ind = 0;
  963.     if (s1[0] == '(' && SearchCorOpenbracket(s1, 0) == s2 - s1 - 1)
  964.     {
  965.         s1++;
  966.         s2--;
  967.         ind = 1;
  968.     }
  969.     if (s1 == s2)
  970.     {
  971.         delete[]s;
  972.         s = new char[1];        // ISO C++ forbids initialization in array new
  973.         s[0] = 0;
  974.         return;
  975.     }
  976.     if (s1[0] == ' ')
  977.     {
  978.         ind = 1;
  979.         while (s1[0] == ' ' && s1 < s2)
  980.             s1++;
  981.     }
  982.     if (s1 == s2)
  983.     {
  984.         delete[]s;
  985.         s = new char[1];        // ISO C++ forbids initialization in array new
  986.         s[0] = 0;
  987.         return;
  988.     }
  989.     if (*(s2 - 1) == ' ')
  990.     {
  991.         ind = 1;
  992.         while (s2 > s1 && *(s2 - 1) == ' ')
  993.             s2--;
  994.     }
  995.     *s2 = 0;
  996.     s1 = CopyStr(s1);
  997.     delete[]s;
  998.     s = s1;
  999.     if (ind)
  1000.         SimplifyStr(s);
  1001. }
  1002.  
  1003. int max(int a, int b)
  1004. {
  1005.     return (a > b ? a : b);
  1006. }
  1007.  
  1008. int IsVar(const char *s, int n, int nvar, PRVar * ppvar)
  1009. {
  1010.     if (n < 0 || n > (int)strlen(s))
  1011.         return 0;
  1012.     int i;
  1013.     int l = 0;
  1014.     for (i = 0; i < nvar; i++)
  1015.         if (CompStr(s, n, (*(ppvar + i))->name))
  1016.             l = max(l, strlen((*(ppvar + i))->name));
  1017.     return l;
  1018. }
  1019.  
  1020. int IsFunction(const char *s, int n)
  1021. {
  1022.     if (CompStr(s, n, "sin") || CompStr(s, n, "cos") || CompStr(s, n, "exp")
  1023.         || CompStr(s, n, "tan") || CompStr(s, n, "log") || CompStr(s, n, "atg")
  1024.         || CompStr(s, n, "abs"))
  1025.         return 3;
  1026.     if (CompStr(s, n, "tg") || CompStr(s, n, "ln"))
  1027.         return 2;
  1028.     if (CompStr(s, n, "sqrt") || CompStr(s, n, "asin") || CompStr(s, n, "atan")
  1029.         || CompStr(s, n, "acos"))
  1030.         return 4;
  1031.     if (CompStr(s, n, "arcsin") || CompStr(s, n, "arccos")
  1032.         || CompStr(s, n, "arctan"))
  1033.         return 6;
  1034.     if (CompStr(s, n, "arctg"))
  1035.         return 5;
  1036.     return 0;
  1037. }
  1038.  
  1039. int IsFunction(const char *s, int n, int nfunc, PRFunction * ppfunc)
  1040.     // Not recognized if a user-defined function is eg "sine" ie begins like
  1041.     // a standard function
  1042.     // IF PATCHED TO DO OTHERWISE, SHOULD BE PATCHED TOGETHER WITH THE
  1043.     // PARSER BELOW which treats standard functions before user-defined ones
  1044. {
  1045.     int l = IsFunction(s, n);
  1046.     if (l)
  1047.         return l;
  1048.     int i;
  1049.     l = 0;
  1050.     for (i = 0; i < nfunc; i++)
  1051.         if (CompStr(s, n, ppfunc[i]->name))
  1052.             l = max(l, strlen(ppfunc[i]->name));
  1053.     return l;
  1054. }
  1055.  
  1056. signed char IsFunction(ROperator op)
  1057. {
  1058.     return (op == Exp || op == Abs || op == Sin || op == Cos || op == Tg
  1059.             || op == Ln || op == Atan || op == Asin || op == Acos || op == Atan
  1060.             || op == Sqrt || op == Opp);
  1061. }
  1062.  
  1063. void IsolateVars(char *&s, int nvar, PRVar * ppvar, int nfunc, PRFunction * ppfunc) // Deletes
  1064.                                                                                     // the
  1065.                                                                                     // old
  1066.                                                                                     // string
  1067. {
  1068.     int i, j;
  1069.     i = 0;
  1070.     for (i = 0; s[i]; i++)
  1071.     {
  1072.         if (s[i] == '(')
  1073.         {
  1074.             i = SearchCorOpenbracket(s, i);
  1075.             if (i == -1)
  1076.                 return;
  1077.             continue;
  1078.         };
  1079.         if (((j = IsVar(s, i, nvar, ppvar)) > IsFunction(s, i, nfunc, ppfunc))
  1080.             ||
  1081.             ((CompStr(s, i, "pi") || CompStr(s, i, "PI")
  1082.               || CompStr(s, i, "Pi")) && (j = 2)))
  1083.         {
  1084.             InsStr(s, i, '(');
  1085.             InsStr(s, i + j + 1, ')');
  1086.             i += j + 1;
  1087.             continue;
  1088.         };
  1089.         if (IsFunction(s, i, nfunc, ppfunc))
  1090.         {
  1091.             i += IsFunction(s, i, nfunc, ppfunc) - 1;
  1092.             if (!s[i])
  1093.                 return;
  1094.             continue;
  1095.         };
  1096.     };
  1097. }
  1098.  
  1099. void IsolateNumbers(char *&s, int nvar, RVar ** ppvar, int nfunc, RFunction ** ppfunc)  // Deletes
  1100.                                                                                         // the
  1101.                                                                                         // old
  1102.                                                                                         // string
  1103. {
  1104.     int i, i2, ind = 0, t1, t2;
  1105.     for (i = 0; s[i]; i++)
  1106.     {
  1107.         if (ind && !IsNumeric(s[i]))
  1108.         {
  1109.             ind = 0;
  1110.             InsStr(s, i2, '(');
  1111.             i++;
  1112.             InsStr(s, i, ')');
  1113.             continue;
  1114.         };
  1115.         t1 = IsVar(s, i, nvar, ppvar);
  1116.         t2 = IsFunction(s, i, nfunc, ppfunc);
  1117.         if (t1 || t2)
  1118.         {
  1119.             i += max(t1, t2) - 1;
  1120.             continue;
  1121.         };
  1122.         if (s[i] == '(')
  1123.         {
  1124.             i = SearchCorOpenbracket(s, i);
  1125.             if (i == -1)
  1126.                 return;
  1127.             continue;
  1128.         };
  1129.         if (!ind && IsNumeric(s[i]))
  1130.         {
  1131.             i2 = i;
  1132.             ind = 1;
  1133.         };
  1134.     };
  1135.     if (ind)
  1136.         InsStr(s, i2, '(');
  1137.     i++;
  1138.     InsStr(s, i, ')');
  1139. }
  1140.  
  1141. ROperation::ROperation(char *sp, int nvar, PRVar * ppvarp, int nfuncp,
  1142.                        PRFunction * ppfuncp)
  1143. {
  1144.     ValC = ErrVal;
  1145.     mmb1 = NULL;
  1146.     mmb2 = NULL;
  1147.     pvar = NULL;
  1148.     op = ErrOp;
  1149.     pvarval = NULL;
  1150.     containfuncflag = 0;
  1151.     pfunc = NULL;
  1152.     pinstr = NULL;
  1153.     pvals = NULL;
  1154.     ppile = NULL;
  1155.     pfuncpile = NULL;
  1156.     int i, j, k, l;
  1157.     signed char flag = 1;
  1158.     char *s = CopyStr(sp), *s1 = NULL, *s2 = NULL;
  1159.     SimplifyStr(s);
  1160.     if (!s[0] || !strcmp(s, "error"))
  1161.     {
  1162.         goto fin;
  1163.     }
  1164.     while (s[0] == ':' || s[0] == ';')
  1165.     {
  1166.         s1 = CopyStr(s + 1);
  1167.         delete[]s;
  1168.         s = s1;
  1169.         s1 = NULL;
  1170.         SimplifyStr(s);
  1171.         if (!s[0] || !strcmp(s, "error"))
  1172.         {
  1173.             goto fin;
  1174.         }
  1175.     }
  1176.     if (IsTNumeric(s))
  1177.     {
  1178.         op = Num;
  1179.         ValC = atof(s);
  1180.         mmb1 = NULL;
  1181.         mmb2 = NULL;
  1182.         goto fin;
  1183.     };
  1184.     if (EqStr(s, "pi") || EqStr(s, "PI") || EqStr(s, "Pi"))
  1185.     {
  1186.         op = Num;
  1187.         ValC = 3.141592653589793238462643383279L;
  1188.         mmb1 = NULL;
  1189.         mmb2 = NULL;
  1190.         goto fin;
  1191.     };
  1192.     if (IsFunction(s, 0, nfuncp, ppfuncp) < IsVar(s, 0, nvar, ppvarp))
  1193.         for (i = 0; i < nvar; i++)
  1194.             if (EqStr(s, (*(ppvarp + i))->name))
  1195.             {
  1196.                 pvar = ppvarp[i];
  1197.                 pvarval = pvar->pval;
  1198.                 op = Var;
  1199.                 mmb1 = NULL;
  1200.                 mmb2 = NULL;
  1201.                 goto fin;
  1202.             };
  1203.     for (k = 0; s[k]; k++)
  1204.     {
  1205.         if (s[k] == '(')
  1206.         {
  1207.             k = SearchCorOpenbracket(s, k);
  1208.             if (k == -1)
  1209.                 break;
  1210.             continue;
  1211.         };
  1212.         if ((l = IsFunction(s, k, nfuncp, ppfuncp))
  1213.             && l >= IsVar(s, k, nvar, ppvarp))
  1214.         {
  1215.             i = k + l;
  1216.             while (s[i] == ' ')
  1217.                 i++;
  1218.             if (s[i] == '(')
  1219.             {
  1220.                 j = SearchCorOpenbracket(s, i);
  1221.                 if (j != -1)
  1222.                 {
  1223.                     InsStr(s, i, ';');
  1224.                     k = j + 1;
  1225.                 }
  1226.                 else
  1227.                     break;
  1228.             }
  1229.             else if (s[i] != ':' && s[i] != ';')
  1230.             {
  1231.                 InsStr(s, i, ':');
  1232.                 k = i;
  1233.             }
  1234.         }
  1235.     }
  1236.     IsolateNumbers(s, nvar, ppvarp, nfuncp, ppfuncp);
  1237.     if (nvar)
  1238.         IsolateVars(s, nvar, ppvarp, nfuncp, ppfuncp);
  1239.     SupprSpaces(s);
  1240.     i = SearchOperator(s, Juxt);
  1241.     if (i != -1)
  1242.     {
  1243.         s1 = MidStr(s, 0, i - 1);
  1244.         s2 = MidStr(s, i + 1, strlen(s) - 1);
  1245.         op = Juxt;
  1246.         mmb1 = new ROperation(s1, nvar, ppvarp, nfuncp, ppfuncp);
  1247.         mmb2 = new ROperation(s2, nvar, ppvarp, nfuncp, ppfuncp);
  1248.         goto fin;
  1249.     };
  1250.     i = SearchOperator(s, Add);
  1251.     if (i != -1)
  1252.     {
  1253.         s1 = MidStr(s, 0, i - 1);
  1254.         s2 = MidStr(s, i + 1, strlen(s) - 1);
  1255.         op = Add;
  1256.         mmb1 = new ROperation(s1, nvar, ppvarp, nfuncp, ppfuncp);
  1257.         mmb2 = new ROperation(s2, nvar, ppvarp, nfuncp, ppfuncp);
  1258.         goto fin;
  1259.     };
  1260.     i = SearchOperator(s, Sub);
  1261.     if (i != -1)
  1262.     {
  1263.         s1 = MidStr(s, 0, i - 1);
  1264.         s2 = MidStr(s, i + 1, strlen(s) - 1);
  1265.         op = Sub;
  1266.         mmb1 = new ROperation(s1, nvar, ppvarp, nfuncp, ppfuncp);
  1267.         mmb2 = new ROperation(s2, nvar, ppvarp, nfuncp, ppfuncp);
  1268.         goto fin;
  1269.     };
  1270.     if (s[0] == '-')
  1271.     {
  1272.         s2 = MidStr(s, 1, strlen(s) - 1);
  1273.         op = Opp;
  1274.         mmb1 = NULL;
  1275.         mmb2 = new ROperation(s2, nvar, ppvarp, nfuncp, ppfuncp);
  1276.         goto fin;
  1277.     };
  1278.     for (i = 0; s[i]; i++)
  1279.     {
  1280.         if (s[i] == '(')
  1281.         {
  1282.             i = SearchCorOpenbracket(s, i);
  1283.             if (i == -1)
  1284.                 break;
  1285.             continue;
  1286.         };
  1287.         if (IsFunction(s, i, nfuncp, ppfuncp))
  1288.         {
  1289.             k = i + IsFunction(s, i, nfuncp, ppfuncp);
  1290.             while (s[k] == ' ')
  1291.                 k++;
  1292.             if (s[k] == ';')
  1293.             {
  1294.                 // s=DelStr(s,k);
  1295.                 j = k;
  1296.                 while (s[j] != '(')
  1297.                     j++;
  1298.                 j = SearchCorOpenbracket(s, j);
  1299.                 if (j != -1)
  1300.                 {
  1301.                     InsStr(s, j, ')');
  1302.                     InsStr(s, i, '(');
  1303.                     i = j + 2;
  1304.                 }
  1305.             }
  1306.             else if (s[k] == ':')
  1307.             {
  1308.                 // s=DelStr(s,k);
  1309.                 for (j = k; s[j]; j++)
  1310.                     if (s[j] == '(')
  1311.                     {
  1312.                         j = SearchCorOpenbracket(s, j);
  1313.                         break;
  1314.                     }
  1315.                 if (j == -1)
  1316.                     break;
  1317.                 for (j++; s[j]; j++)
  1318.                 {
  1319.                     if (s[j] == '(')
  1320.                     {
  1321.                         j = SearchCorOpenbracket(s, j);
  1322.                         if (j == -1)
  1323.                         {
  1324.                             flag = 0;
  1325.                             break;
  1326.                         };
  1327.                         continue;
  1328.                     };
  1329.                     if (IsFunction(s, j, nfuncp, ppfuncp))
  1330.                         break;
  1331.                 }
  1332.                 if (flag == 0)
  1333.                 {
  1334.                     flag = 1;
  1335.                     break;
  1336.                 }
  1337.                 while (j > i && s[j - 1] != ')')
  1338.                     j--;
  1339.                 if (j <= i + 1)
  1340.                     break;
  1341.                 InsStr(s, i, '(');
  1342.                 InsStr(s, j + 1, ')');
  1343.                 i = j + 1;
  1344.             }
  1345.         }
  1346.     }
  1347.     for (i = 0; s[i] && s[i + 1]; i++)
  1348.         if (s[i] == ')' && s[i + 1] == '(')
  1349.             InsStr(s, ++i, '*');
  1350.     if (s[0] == '(' && SearchCorOpenbracket(s, 0) == (int)strlen(s) - 1)
  1351.     {
  1352.         if (CompStr(s, 1, "exp"))
  1353.         {
  1354.             op = Exp;
  1355.             s2 = MidStr(s, 4, strlen(s) - 2);
  1356.         }
  1357.         else if (CompStr(s, 1, "abs"))
  1358.         {
  1359.             op = Abs;
  1360.             s2 = MidStr(s, 4, strlen(s) - 2);
  1361.         }
  1362.         else if (CompStr(s, 1, "sin"))
  1363.         {
  1364.             op = Sin;
  1365.             s2 = MidStr(s, 4, strlen(s) - 2);
  1366.         }
  1367.         else if (CompStr(s, 1, "cos"))
  1368.         {
  1369.             op = Cos;
  1370.             s2 = MidStr(s, 4, strlen(s) - 2);
  1371.         }
  1372.         else if (CompStr(s, 1, "tan"))
  1373.         {
  1374.             op = Tg;
  1375.             s2 = MidStr(s, 4, strlen(s) - 2);
  1376.         }
  1377.         else if (CompStr(s, 1, "log"))
  1378.         {
  1379.             op = Ln;
  1380.             s2 = MidStr(s, 4, strlen(s) - 2);
  1381.         }
  1382.         else if (CompStr(s, 1, "atg"))
  1383.         {
  1384.             op = Atan;
  1385.             s2 = MidStr(s, 4, strlen(s) - 2);
  1386.         }
  1387.         else if (CompStr(s, 1, "tg"))
  1388.         {
  1389.             op = Tg;
  1390.             s2 = MidStr(s, 3, strlen(s) - 2);
  1391.         }
  1392.         else if (CompStr(s, 1, "ln"))
  1393.         {
  1394.             op = Ln;
  1395.             s2 = MidStr(s, 3, strlen(s) - 2);
  1396.         }
  1397.         else if (CompStr(s, 1, "asin"))
  1398.         {
  1399.             op = Asin;
  1400.             s2 = MidStr(s, 5, strlen(s) - 2);
  1401.         }
  1402.         else if (CompStr(s, 1, "acos"))
  1403.         {
  1404.             op = Acos;
  1405.             s2 = MidStr(s, 5, strlen(s) - 2);
  1406.         }
  1407.         else if (CompStr(s, 1, "atan"))
  1408.         {
  1409.             op = Atan;
  1410.             s2 = MidStr(s, 5, strlen(s) - 2);
  1411.         }
  1412.         else if (CompStr(s, 1, "sqrt"))
  1413.         {
  1414.             op = Sqrt;
  1415.             s2 = MidStr(s, 5, strlen(s) - 2);
  1416.         }
  1417.         else if (CompStr(s, 1, "arcsin"))
  1418.         {
  1419.             op = Asin;
  1420.             s2 = MidStr(s, 7, strlen(s) - 2);
  1421.         }
  1422.         else if (CompStr(s, 1, "arccos"))
  1423.         {
  1424.             op = Acos;
  1425.             s2 = MidStr(s, 7, strlen(s) - 2);
  1426.         }
  1427.         else if (CompStr(s, 1, "arctan"))
  1428.         {
  1429.             op = Atan;
  1430.             s2 = MidStr(s, 7, strlen(s) - 2);
  1431.         }
  1432.         else if (CompStr(s, 1, "arctg"))
  1433.         {
  1434.             op = Atan;
  1435.             s2 = MidStr(s, 6, strlen(s) - 2);
  1436.         }
  1437.         else
  1438.         {
  1439.             for (i = -1, k = 0, j = 0; j < nfuncp; j++)
  1440.                 if (CompStr(s, 1, ppfuncp[j]->name)
  1441.                     && k < (int)strlen(ppfuncp[j]->name))
  1442.                 {
  1443.                     k = strlen(ppfuncp[j]->name);
  1444.                     i = j;
  1445.                 }
  1446.             if (i > -1)
  1447.             {
  1448.                 op = Fun;
  1449.                 s2 = MidStr(s, strlen(ppfuncp[i]->name) + 1, strlen(s) - 2);
  1450.                 pfunc = ppfuncp[i];
  1451.             }
  1452.         }
  1453.         mmb1 = NULL;
  1454.         mmb2 = new ROperation(s2, nvar, ppvarp, nfuncp, ppfuncp);
  1455.         if (op == Fun)
  1456.             if (mmb2->NMembers() != pfunc->nvars)
  1457.             {
  1458.                 op = ErrOp;
  1459.                 mmb1 = NULL;
  1460.                 mmb2 = NULL;
  1461.                 goto fin;
  1462.             }
  1463.         goto fin;
  1464.     };
  1465.     i = SearchOperator(s, Mult);
  1466.     if (i != -1)
  1467.     {
  1468.         s1 = MidStr(s, 0, i - 1);
  1469.         s2 = MidStr(s, i + 1, strlen(s) - 1);
  1470.         op = Mult;
  1471.         mmb1 = new ROperation(s1, nvar, ppvarp, nfuncp, ppfuncp);
  1472.         mmb2 = new ROperation(s2, nvar, ppvarp, nfuncp, ppfuncp);
  1473.         goto fin;
  1474.     };
  1475.     i = SearchOperator(s, Div);
  1476.     if (i != -1)
  1477.     {
  1478.         s1 = MidStr(s, 0, i - 1);
  1479.         s2 = MidStr(s, i + 1, strlen(s) - 1);
  1480.         op = Div;
  1481.         mmb1 = new ROperation(s1, nvar, ppvarp, nfuncp, ppfuncp);
  1482.         mmb2 = new ROperation(s2, nvar, ppvarp, nfuncp, ppfuncp);
  1483.         goto fin;
  1484.     };
  1485.     i = SearchOperator(s, Pow);
  1486.     if (i != -1)
  1487.     {
  1488.         s1 = MidStr(s, 0, i - 1);
  1489.         s2 = MidStr(s, i + 1, strlen(s) - 1);
  1490.         op = Pow;
  1491.         mmb1 = new ROperation(s1, nvar, ppvarp, nfuncp, ppfuncp);
  1492.         mmb2 = new ROperation(s2, nvar, ppvarp, nfuncp, ppfuncp);
  1493.         goto fin;
  1494.     };
  1495.     i = SearchOperator(s, NthRoot);
  1496.     if (i != -1)
  1497.     {
  1498.         s1 = MidStr(s, 0, i - 1);
  1499.         s2 = MidStr(s, i + 1, strlen(s) - 1);
  1500.         if (i == 0 || s[i - 1] != ')')
  1501.         {
  1502.             op = Sqrt;
  1503.             mmb1 = NULL;
  1504.         }
  1505.         else
  1506.         {
  1507.             op = NthRoot;
  1508.             mmb1 = new ROperation(s1, nvar, ppvarp, nfuncp, ppfuncp);
  1509.         };
  1510.         mmb2 = new ROperation(s2, nvar, ppvarp, nfuncp, ppfuncp);
  1511.         goto fin;
  1512.     };
  1513.     i = SearchOperator(s, E10);
  1514.     if (i != -1)
  1515.     {
  1516.         s1 = MidStr(s, 0, i - 1);
  1517.         s2 = MidStr(s, i + 1, strlen(s) - 1);
  1518.         op = E10;
  1519.         mmb1 = new ROperation(s1, nvar, ppvarp, nfuncp, ppfuncp);
  1520.         mmb2 = new ROperation(s2, nvar, ppvarp, nfuncp, ppfuncp);
  1521.         goto fin;
  1522.     };
  1523.     op = ErrOp;
  1524.     mmb1 = NULL;
  1525.     mmb2 = NULL;
  1526.   fin:
  1527.     BuildCode();
  1528.     delete[]s;
  1529.     if (s1 != NULL)
  1530.         delete[]s1;
  1531.     if (s2 != NULL)
  1532.         delete[]s2;
  1533. }
  1534.  
  1535. void ROperation::Destroy()
  1536. {
  1537.     if (mmb1 != NULL && mmb2 != NULL && mmb1 != mmb2)
  1538.     {
  1539.         delete mmb1;
  1540.         delete mmb2;
  1541.         mmb1 = NULL;
  1542.         mmb2 = NULL;
  1543.     }
  1544.     else if (mmb1 != NULL)
  1545.     {
  1546.         delete mmb1;
  1547.         mmb1 = NULL;
  1548.     }
  1549.     else if (mmb2 != NULL)
  1550.     {
  1551.         delete mmb2;
  1552.         mmb2 = NULL;
  1553.     }
  1554.     if (pinstr != NULL)
  1555.     {
  1556.         delete[]pinstr;
  1557.         pinstr = NULL;
  1558.     }
  1559.     if (pvals != NULL)
  1560.     {
  1561.         if (op == ErrOp || op == Num)
  1562.             delete pvals[0];
  1563.         delete[]pvals;
  1564.         pvals = NULL;
  1565.     }
  1566.     if (ppile != NULL)
  1567.     {
  1568.         delete[]ppile;
  1569.         ppile = NULL;
  1570.     }
  1571.     if (pfuncpile != NULL)
  1572.     {
  1573.         delete[]pfuncpile;
  1574.         pfuncpile = NULL;
  1575.     }
  1576. }
  1577.  
  1578. int operator==(const RVar & var1, const RVar & var2)
  1579. {
  1580.     return (var1.pval == var2.pval && EqStr(var1.name, var2.name));
  1581. }
  1582.  
  1583. int operator==(const RFunction & f1, const RFunction & f2)
  1584. {
  1585.     if (f1.type != f2.type)
  1586.         return 0;
  1587.     if (f1.type == -1)
  1588.         return 1;               // Nonfunction==nonfunction
  1589.     if (f1.type == 0)
  1590.         return (f1.pfuncval == f2.pfuncval && EqStr(f1.name, f2.name));
  1591.     if (f1.op != f2.op)
  1592.         return 0;
  1593.     if (!EqStr(f1.name, f2.name))
  1594.         return 0;
  1595.     if (f1.nvars != f2.nvars)
  1596.         return 0;
  1597.     int i;
  1598.     for (i = 0; i < f1.nvars; i++)
  1599.         if (!(*f1.ppvar[i] == *f2.ppvar[i]))
  1600.             return 0;
  1601.     return 1;
  1602. }
  1603.  
  1604. /*
  1605.    double ROperation::Val() const // Won't work if multi-variable functions
  1606.    are included { double v1=ErrVal,v2=ErrVal;
  1607.    if(mmb1!=NULL){v1=mmb1->Val();if(fabsl(v1)<sqrtminfloat)v1=0;else
  1608.    if(v1==ErrVal||fabsl(v1)>sqrtmaxfloat)return ErrVal;};
  1609.    if(mmb2!=NULL){v2=mmb2->Val();if(fabsl(v2)<sqrtminfloat)v2=0;else
  1610.    if(v2==ErrVal||fabsl(v2)>sqrtmaxfloat)return ErrVal;}; switch(op){ case
  1611.    Num:return ValC; case Var:return *pvarval; case Add:return v1+v2; case
  1612.    Sub:return v1-v2; case Opp:return -v2; case Mult:return v1*v2; case
  1613.    Div:if(v2)return v1/v2;else return ErrVal; case Pow:if(v1==0)return 0;else
  1614.    if((v1>0||!fmodl(v2,1))&&v2*logl(fabsl(v1))<DBL_MAX_EXP)return
  1615.    powl(v1,v2);else return ErrVal; case Sqrt:if(v2>=0)return sqrtl(v2);else
  1616.    return ErrVal; case NthRoot:if(!v1||v2*logl(fabsl(v1))<DBL_MIN_EXP)return
  1617.    ErrVal; else if(v2>=0)return powl(v2,1/v1);else
  1618.    if(fmodl(v1,2)==1||fmodl(v1,2)==-1)return -powl(-v2,1/v1);else return
  1619.    ErrVal; case E10:if(v2<DBL_MAX_10_EXP)return v1*pow10l(v2);else return
  1620.    ErrVal; case Ln:if(v2>0)return logl(v2);else return ErrVal; case
  1621.    Exp:if(v2<DBL_MAX_EXP)return expl(v2);else return ErrVal; case
  1622.    Sin:if(fabsl(v2)<inveps)return sinl(v2);else return ErrVal; case
  1623.    Cos:if(fabsl(v2)<inveps)return cosl(v2);else return ErrVal; case
  1624.    Tg:if(fabsl(v2)<inveps)return tanl(v2);else return ErrVal; case Atan:
  1625.    if(mmb2->op==Juxt){v1=mmb2->NthMember(1).Val();v2=mmb2->NthMember(2).Val();return
  1626.    (v1||v2?atan2(v1,v2):ErrVal);}else return atanl(v2); case
  1627.    Asin:if(v2<-1||v2>1)return ErrVal;else return asinl(v2); case
  1628.    Acos:if(v2<-1||v2>1)return ErrVal;else return acosl(v2); case Abs:return
  1629.    fabsl(v2); case Fun:return pfunc->Val(v2); default:return ErrVal; }; } */
  1630.  
  1631. signed char ROperation::ContainVar(const RVar & varp) const const
  1632. {
  1633.     if (op == Var)
  1634.     {
  1635.         if (EqStr(pvar->name, varp.name) && pvar->pval == varp.pval)
  1636.             return 1;
  1637.         else
  1638.             return 0;
  1639.     };
  1640.     if (mmb1 != NULL && mmb1->ContainVar(varp))
  1641.         return 1;
  1642.     if (mmb2 != NULL && mmb2->ContainVar(varp))
  1643.         return 1;
  1644.     return 0;
  1645. }
  1646.  
  1647. signed char ROperation::ContainFuncNoRec(const RFunction & func) const const    // No
  1648.                                                                                 // recursive
  1649.                                                                                 // test
  1650.                                                                                 // on
  1651.                                                                                 // subfunctions
  1652. {
  1653.     if (op == Fun)
  1654.     {
  1655.         if (*pfunc == func)
  1656.             return 1;
  1657.         else
  1658.             return 0;
  1659.     }
  1660.     if (mmb1 != NULL && mmb1->ContainFuncNoRec(func))
  1661.         return 1;
  1662.     if (mmb2 != NULL && mmb2->ContainFuncNoRec(func))
  1663.         return 1;
  1664.     return 0;
  1665. }
  1666.  
  1667. signed char ROperation::ContainFunc(const RFunction & func) const const // Recursive
  1668.                                                                         // test
  1669.                                                                         // on
  1670.                                                                         // subfunctions
  1671. {
  1672.     if (containfuncflag)
  1673.         return 0;
  1674.     if (op == Fun && *pfunc == func)
  1675.         return 1;
  1676.     containfuncflag = 1;
  1677.     if (op == Fun)
  1678.         if (pfunc->op.ContainFunc(func))
  1679.         {
  1680.             containfuncflag = 0;
  1681.             return 1;
  1682.         }
  1683.     if (mmb1 != NULL && mmb1->ContainFunc(func))
  1684.     {
  1685.         containfuncflag = 0;
  1686.         return 1;
  1687.     }
  1688.     if (mmb2 != NULL && mmb2->ContainFunc(func))
  1689.     {
  1690.         containfuncflag = 0;
  1691.         return 1;
  1692.     }
  1693.     containfuncflag = 0;
  1694.     return 0;
  1695. }
  1696.  
  1697. signed char ROperation::HasError(const ROperation * pop) const const
  1698. {
  1699.     if (op == ErrOp)
  1700.         return 1;
  1701.     if (op == Fun && pfunc->type == 1
  1702.         && pfunc->op == *(pop == NULL ? this : pop))
  1703.         return 1;
  1704.     if (op == Fun && pfunc->type == 1
  1705.         && pfunc->op.HasError((pop == NULL ? this : pop)))
  1706.         return 1;
  1707.     if (mmb1 != NULL && mmb1->HasError((pop == NULL ? this : pop)))
  1708.         return 1;
  1709.     if (mmb2 != NULL && mmb2->HasError((pop == NULL ? this : pop)))
  1710.         return 1;
  1711.     if (op == Fun && pfunc->type == -1)
  1712.         return 1;
  1713.     return 0;
  1714. }
  1715.  
  1716. int ROperation::NMembers() const const  // Number of members for an operation
  1717.                                         // like a,b,c...
  1718. {
  1719.     if (op == Fun)
  1720.         return (pfunc->type == 1 ? pfunc->op.NMembers() : pfunc->type ==
  1721.                 0 ? 1 : 0);
  1722.     if (op != Juxt)
  1723.         return 1;
  1724.     else if (mmb2 == NULL)
  1725.         return 0;
  1726.     else
  1727.         return 1 + mmb2->NMembers();
  1728. }
  1729.  
  1730. ROperation ROperation::NthMember(int n) constconst
  1731. {
  1732.     PRFunction prf;
  1733.     if (op == Fun && pfunc->type == 1 && pfunc->op.NMembers() > 1)
  1734.     {
  1735.         prf =
  1736.             new RFunction(pfunc->op.NthMember(n), pfunc->nvars, pfunc->ppvar);
  1737.         char *s = new char[strlen(pfunc->name) + 10];
  1738.         sprintf(s, "(%s_%i)", pfunc->name, n);
  1739.         prf->SetName(s);
  1740.         delete[]s;
  1741.         return (*prf) (*mmb2);
  1742.     }
  1743.     if (n == 1)
  1744.     {
  1745.         if (op != Juxt)
  1746.             return *this;
  1747.         else if (mmb1 != NULL)
  1748.             return *mmb1;
  1749.         else
  1750.             return ErrVal;
  1751.     };
  1752.     if (op != Juxt)
  1753.         return ErrVal;
  1754.     if (n > 1 && mmb2 != NULL)
  1755.         return mmb2->NthMember(n - 1);
  1756.     return ErrVal;
  1757. }
  1758.  
  1759. ROperation ROperation::Substitute(const RVar & var, const ROperation & rop) constconst  // Replaces
  1760.                                                                                         // variable
  1761.                                                                                         // var
  1762.                                                                                         // with
  1763.                                                                                         // expression
  1764.                                                                                         // rop
  1765. {
  1766.     if (!ContainVar(var))
  1767.         return *this;
  1768.     if (op == Var)
  1769.         return rop;
  1770.     ROperation r;
  1771.     r.op = op;
  1772.     r.pvar = pvar;
  1773.     r.pvarval = pvarval;
  1774.     r.ValC = ValC;
  1775.     r.pfunc = pfunc;
  1776.     if (mmb1 != NULL)
  1777.         r.mmb1 = new ROperation(mmb1->Substitute(var, rop));
  1778.     else
  1779.         r.mmb1 = NULL;
  1780.     if (mmb2 != NULL)
  1781.         r.mmb2 = new ROperation(mmb2->Substitute(var, rop));
  1782.     else
  1783.         r.mmb2 = NULL;
  1784.     return r;
  1785. }
  1786.  
  1787. ROperation ROperation::Diff(const RVar & var) constconst
  1788. {
  1789.     if (!ContainVar(var))
  1790.         return 0.0;
  1791.     if (op == Var)
  1792.         return 1.0;
  1793.     ROperation **ppop1, op2;
  1794.     int i, j;
  1795.     switch (op)
  1796.     {
  1797.     case Juxt:
  1798.         return (mmb1->Diff(var), mmb2->Diff(var));
  1799.     case Add:
  1800.         return (mmb1->Diff(var) + mmb2->Diff(var));
  1801.     case Sub:
  1802.         return (mmb1->Diff(var) - mmb2->Diff(var));
  1803.     case Opp:
  1804.         return (-mmb2->Diff(var));
  1805.     case Mult:
  1806.         return ((*mmb1) * (mmb2->Diff(var)) + (*mmb2) * (mmb1->Diff(var)));
  1807.     case Div:
  1808.         if (mmb2->ContainVar(var))
  1809.             return (((*mmb2) * (mmb1->Diff(var)) -
  1810.                      (*mmb1) * (mmb2->Diff(var))) / ((*mmb2) ^ 2));
  1811.         else
  1812.             return (mmb1->Diff(var) / (*mmb2));
  1813.     case Pow:
  1814.         if (mmb2->ContainVar(var))
  1815.             return ((*this) * (log(*mmb1) * mmb2->Diff(var) +
  1816.                                (*mmb2) * mmb1->Diff(var) / (*mmb1)));
  1817.         else
  1818.             return (*mmb2) * mmb1->Diff(var) * ((*mmb1) ^ (*mmb2 - 1));
  1819.     case Sqrt:
  1820.         return (mmb2->Diff(var) / (2 * sqrt(*mmb2)));
  1821.     case NthRoot:
  1822.         {
  1823.             ROperation interm = (*mmb2) ^ (1 / (*mmb1));
  1824.             return interm.Diff(var);
  1825.         };
  1826.     case E10:
  1827.         {
  1828.             ROperation interm = (*mmb1) * (10 ^ (*mmb2));
  1829.             return interm.Diff(var);
  1830.         };;
  1831.     case Ln:
  1832.         return (mmb2->Diff(var) / (*mmb2));
  1833.     case Exp:
  1834.         return (mmb2->Diff(var) * (*this));
  1835.     case Sin:
  1836.         return (mmb2->Diff(var) * cos(*mmb2));
  1837.     case Cos:
  1838.         return (-mmb2->Diff(var) * sin(*mmb2));
  1839.     case Tg:
  1840.         return (mmb2->Diff(var) * (1 + ((*this) ^ 2)));
  1841.     case Atan:
  1842.         if (mmb2->op != Juxt)
  1843.             return (mmb2->Diff(var) / (1 + ((*mmb2) ^ 2)));
  1844.         else
  1845.             return ((mmb2->NthMember(1).Diff(var)) * (mmb2->NthMember(2)) -
  1846.                     (mmb2->NthMember(2).Diff(var)) * (mmb2->NthMember(1))) /
  1847.                 (((mmb2->NthMember(1)) ^ 2) + ((mmb2->NthMember(2)) ^ 2));
  1848.     case Asin:
  1849.         return (mmb2->Diff(var) / sqrt(1 - ((*mmb2) ^ 2)));
  1850.     case Acos:
  1851.         return (-mmb2->Diff(var) / sqrt(1 - ((*mmb2) ^ 2)));
  1852.     case Abs:
  1853.         return (mmb2->Diff(var) * (*mmb2) / (*this));
  1854.     case Fun:
  1855.         if (pfunc->type == -1 || pfunc->type == 0)
  1856.             return ErrVal;
  1857.         if (pfunc->nvars == 0)
  1858.             return 0.;
  1859.         else if (pfunc->op.NMembers() > 1)
  1860.         {
  1861.             j = pfunc->op.NMembers();
  1862.             ppop1 = new ROperation *[j];
  1863.             for (i = 0; i < j; i++)
  1864.                 ppop1[i] = new ROperation(NthMember(i + 1).Diff(var));
  1865.             op2 = ApplyOperator(pfunc->nvars, ppop1, &operator,);
  1866.             for (i = 0; i < pfunc->nvars; i++)
  1867.                 delete ppop1[i];
  1868.             delete[]ppop1;
  1869.             return op2;
  1870.         }
  1871.         else
  1872.         {
  1873.             ppop1 = new ROperation *[pfunc->nvars];
  1874.             for (i = 0; i < pfunc->nvars; i++)
  1875.             {
  1876.                 ppop1[i] = new ROperation(pfunc->op.Diff(*pfunc->ppvar[i]));
  1877.                 for (j = 0; j < pfunc->nvars; j++)
  1878.                     *ppop1[i] =
  1879.                         ppop1[i]->Substitute(*pfunc->ppvar[j],
  1880.                                              mmb2->NthMember(j + 1));
  1881.                 *ppop1[i] = (mmb2->NthMember(i + 1).Diff(var)) * (*ppop1[i]);
  1882.             }
  1883.             op2 = ApplyOperator(pfunc->nvars, ppop1, &::operator+);
  1884.             for (i = 0; i < pfunc->nvars; i++)
  1885.                 delete ppop1[i];
  1886.             delete[]ppop1;
  1887.             return op2;
  1888.             // In the obtained expression, f' will have been replaced with its
  1889.             // expression but f will remain pointing to itself ; this could
  1890.             // cause some trouble if changing f afterwards
  1891.         }
  1892.     default:
  1893.         return ErrVal;
  1894.     };
  1895. }
  1896.  
  1897. char *ValToStr(double x)
  1898. {
  1899.     char *s = new char[30];
  1900.     if (x == (double)3.141592653589793238462643383279L)
  1901.         sprintf(s, "pi");
  1902.     else
  1903.         sprintf(s, "%.16G", x);
  1904.     return s;
  1905. }
  1906.  
  1907. char *ROperation::Expr() const const
  1908. {
  1909.     char *s = NULL, *s1 = NULL, *s2 = NULL;
  1910.     int n = 10;
  1911.     signed char f = 0, g = 0;
  1912.     if (op == Fun)
  1913.         if (strlen(pfunc->name) > 4)
  1914.             n += strlen(pfunc->name) - 4;
  1915.     if (mmb1 != NULL)
  1916.     {
  1917.         s1 = mmb1->Expr();
  1918.         n += strlen(s1);
  1919.         f = IsFunction(mmb1->op);
  1920.     }
  1921.     if (mmb2 != NULL)
  1922.     {
  1923.         s2 = mmb2->Expr();
  1924.         n += strlen(s2);
  1925.         g = IsFunction(mmb2->op);
  1926.     }
  1927.     s = new char[n];
  1928.     switch (op)
  1929.     {
  1930.     case Num:
  1931.         return ValToStr(ValC);
  1932.     case Var:
  1933.         return CopyStr(pvar->name);
  1934.     case Juxt:
  1935.         sprintf(s, "%s , %s", s1, s2);
  1936.         break;
  1937.     case Add:
  1938.         f = f || (mmb1->op == Juxt);
  1939.         g = g || (mmb2->op == Juxt);
  1940.         if (f && g)
  1941.             sprintf(s, "(%s)+(%s)", s1, s2);
  1942.         else if (f)
  1943.             sprintf(s, "(%s)+%s", s1, s2);
  1944.         else if (g)
  1945.             sprintf(s, "%s+(%s)", s1, s2);
  1946.         else
  1947.             sprintf(s, "%s+%s", s1, s2);
  1948.         break;
  1949.     case Sub:
  1950.         f = f || (mmb1->op == Juxt);
  1951.         g = g || (mmb2->op == Juxt || mmb2->op == Add || mmb2->op == Sub);
  1952.         if (f && g)
  1953.             sprintf(s, "(%s)-(%s)", s1, s2);
  1954.         else if (f)
  1955.             sprintf(s, "(%s)-%s", s1, s2);
  1956.         else if (g)
  1957.             sprintf(s, "%s-(%s)", s1, s2);
  1958.         else
  1959.             sprintf(s, "%s-%s", s1, s2);
  1960.         break;
  1961.     case Opp:
  1962.         if (mmb2->op == Add || mmb2->op == Sub || mmb2->op == Juxt)
  1963.             sprintf(s, "-(%s)", s2);
  1964.         else
  1965.             sprintf(s, "-%s", s2);
  1966.         break;
  1967.     case Mult:
  1968.         f = f || (mmb1->op == Juxt || mmb1->op == Add || mmb1->op == Sub
  1969.                   || mmb1->op == Opp || mmb1->op == Div);
  1970.         g = g || (mmb2->op == Juxt || mmb2->op == Add || mmb2->op == Sub
  1971.                   || mmb2->op == Opp);
  1972.         if (f && g)
  1973.             sprintf(s, "(%s)*(%s)", s1, s2);
  1974.         else if (f)
  1975.             sprintf(s, "(%s)*%s", s1, s2);
  1976.         else if (g)
  1977.             sprintf(s, "%s*(%s)", s1, s2);
  1978.         else
  1979.             sprintf(s, "%s*%s", s1, s2);
  1980.         break;
  1981.     case Div:
  1982.         f = f || (mmb1->op == Juxt || mmb1->op == Add || mmb1->op == Sub
  1983.                   || mmb1->op == Opp || mmb1->op == Div);
  1984.         g = g || (mmb2->op == Juxt || mmb2->op == Add || mmb2->op == Sub
  1985.                   || mmb2->op == Opp || mmb2->op == Mult || mmb2->op == Div);
  1986.         if (f && g)
  1987.             sprintf(s, "(%s)/(%s)", s1, s2);
  1988.         else if (f)
  1989.             sprintf(s, "(%s)/%s", s1, s2);
  1990.         else if (g)
  1991.             sprintf(s, "%s/(%s)", s1, s2);
  1992.         else
  1993.             sprintf(s, "%s/%s", s1, s2);
  1994.         break;
  1995.     case Pow:
  1996.         f = (mmb1->op != Num && mmb1->op != Var);
  1997.         g = (mmb2->op != Num && mmb2->op != Var);
  1998.         if (f && g)
  1999.             sprintf(s, "(%s)^(%s)", s1, s2);
  2000.         else if (f)
  2001.             sprintf(s, "(%s)^%s", s1, s2);
  2002.         else if (g)
  2003.             sprintf(s, "%s^(%s)", s1, s2);
  2004.         else
  2005.             sprintf(s, "%s^%s", s1, s2);
  2006.         break;
  2007.     case Sqrt:
  2008.         g = (mmb2->op != Num && mmb2->op != Var && !g);
  2009.         if (g)
  2010.             sprintf(s, "sqrt(%s)", s2);
  2011.         else
  2012.             sprintf(s, "sqrt %s", s2);
  2013.         break;
  2014.     case NthRoot:
  2015.         f = (mmb1->op != Num && mmb1->op != Var);
  2016.         g = (mmb2->op != Num && mmb2->op != Var);
  2017.         if (f && g)
  2018.             sprintf(s, "(%s)#(%s)", s1, s2);
  2019.         else if (f)
  2020.             sprintf(s, "(%s)#%s", s1, s2);
  2021.         else if (g)
  2022.             sprintf(s, "%s#(%s)", s1, s2);
  2023.         else
  2024.             sprintf(s, "%s#%s", s1, s2);
  2025.         break;
  2026.     case E10:
  2027.         f = (mmb1->op != Num && mmb1->op != Var);
  2028.         g = (mmb2->op != Num && mmb2->op != Var);
  2029.         if (f && g)
  2030.             sprintf(s, "(%s)E(%s)", s1, s2);
  2031.         else if (f)
  2032.             sprintf(s, "(%s)E%s", s1, s2);
  2033.         else if (g)
  2034.             sprintf(s, "%sE(%s)", s1, s2);
  2035.         else
  2036.             sprintf(s, "%sE%s", s1, s2);
  2037.         break;
  2038.     case Ln:
  2039.         g = (mmb2->op != Num && mmb2->op != Var && !g);
  2040.         if (g)
  2041.             sprintf(s, "log(%s)", s2);
  2042.         else
  2043.             sprintf(s, "log %s", s2);
  2044.         break;
  2045.     case Exp:
  2046.         g = (mmb2->op != Num && mmb2->op != Var && !g);
  2047.         if (g)
  2048.             sprintf(s, "exp(%s)", s2);
  2049.         else
  2050.             sprintf(s, "exp %s", s2);
  2051.         break;
  2052.     case Sin:
  2053.         g = (mmb2->op != Num && mmb2->op != Var && !g);
  2054.         if (g)
  2055.             sprintf(s, "sin(%s)", s2);
  2056.         else
  2057.             sprintf(s, "sin %s", s2);
  2058.         break;
  2059.     case Cos:
  2060.         g = (mmb2->op != Num && mmb2->op != Var && !g);
  2061.         if (g)
  2062.             sprintf(s, "cos(%s)", s2);
  2063.         else
  2064.             sprintf(s, "cos %s", s2);
  2065.         break;
  2066.     case Tg:
  2067.         g = (mmb2->op != Num && mmb2->op != Var && !g);
  2068.         if (g)
  2069.             sprintf(s, "tan(%s)", s2);
  2070.         else
  2071.             sprintf(s, "tan %s", s2);
  2072.         break;
  2073.     case Atan:
  2074.         g = (mmb2->op != Num && mmb2->op != Var && !g);
  2075.         if (g)
  2076.             sprintf(s, "atan(%s)", s2);
  2077.         else
  2078.             sprintf(s, "atan %s", s2);
  2079.         break;
  2080.     case Asin:
  2081.         g = (mmb2->op != Num && mmb2->op != Var && !g);
  2082.         if (g)
  2083.             sprintf(s, "asin(%s)", s2);
  2084.         else
  2085.             sprintf(s, "asin %s", s2);
  2086.         break;
  2087.     case Acos:
  2088.         g = (mmb2->op != Num && mmb2->op != Var && !g);
  2089.         if (g)
  2090.             sprintf(s, "acos(%s)", s2);
  2091.         else
  2092.             sprintf(s, "acos %s", s2);
  2093.         break;
  2094.     case Abs:
  2095.         g = (mmb2->op != Num && mmb2->op != Var && !g);
  2096.         if (g)
  2097.             sprintf(s, "abs(%s)", s2);
  2098.         else
  2099.             sprintf(s, "abs %s", s2);
  2100.         break;
  2101.     case Fun:
  2102.         sprintf(s, "%s(%s)", pfunc->name, s2);
  2103.         break;
  2104.     default:
  2105.         return CopyStr("error");
  2106.     };
  2107.     if (s1 != NULL)
  2108.         delete[]s1;
  2109.     if (s2 != NULL)
  2110.         delete[]s2;
  2111.     return s;
  2112. }
  2113.  
  2114. const double sqrtmaxfloat = sqrt(DBL_MAX);
  2115. const double sqrtminfloat = sqrt(DBL_MIN);
  2116. const double inveps = .1 / DBL_EPSILON;
  2117.  
  2118. void Addition(double *&p)
  2119. {
  2120.     if (*p == ErrVal || fabsl(*p) > sqrtmaxfloat)
  2121.     {
  2122.         *(--p) = ErrVal;
  2123.         return;
  2124.     };
  2125.     if (*(--p) == ErrVal || fabsl(*p) > sqrtmaxfloat)
  2126.     {
  2127.         *p = ErrVal;
  2128.         return;
  2129.     };
  2130.     *p += (*(p + 1));
  2131. }
  2132.  
  2133. void Soustraction(double *&p)
  2134. {
  2135.     if (*p == ErrVal || fabsl(*p) > sqrtmaxfloat)
  2136.     {
  2137.         *(--p) = ErrVal;
  2138.         return;
  2139.     };
  2140.     if (*(--p) == ErrVal || fabsl(*p) > sqrtmaxfloat)
  2141.     {
  2142.         *p = ErrVal;
  2143.         return;
  2144.     };
  2145.     *p -= (*(p + 1));
  2146. }
  2147.  
  2148. void Multiplication(double *&p)
  2149. {
  2150.     if (fabsl(*p) < sqrtminfloat)
  2151.     {
  2152.         *--p = 0;
  2153.         return;
  2154.     };
  2155.     if (*p == ErrVal || fabsl(*p) > sqrtmaxfloat)
  2156.     {
  2157.         *(--p) = ErrVal;
  2158.         return;
  2159.     };
  2160.     if (fabsl(*(--p)) < sqrtminfloat)
  2161.     {
  2162.         *p = 0;
  2163.         return;
  2164.     };
  2165.     if (*p == ErrVal || fabsl(*p) > sqrtmaxfloat)
  2166.     {
  2167.         *p = ErrVal;
  2168.         return;
  2169.     };
  2170.     *p *= (*(p + 1));
  2171. }
  2172.  
  2173. void Division(double *&p)
  2174. {
  2175.     if (fabsl(*p) < sqrtminfloat || *p == ErrVal || fabsl(*p) > sqrtmaxfloat)
  2176.     {
  2177.         *(--p) = ErrVal;
  2178.         return;
  2179.     };
  2180.     if (fabsl(*(--p)) < sqrtminfloat)
  2181.         *p = 0;
  2182.     else if (*p == ErrVal || fabsl(*p) > sqrtmaxfloat)
  2183.     {
  2184.         *p = ErrVal;
  2185.         return;
  2186.     };
  2187.     *p /= (*(p + 1));
  2188. }
  2189.  
  2190. void Puissance(double *&p)
  2191. {
  2192.     double v2 = *p--, v1 = *p;
  2193.     if (!v1)
  2194.     {
  2195.         *p = 0;
  2196.         return;
  2197.     };
  2198.     if (v2 == ErrVal || v1 == ErrVal
  2199.         || fabsl(v2 * logl(fabsl(v1))) > DBL_MAX_EXP)
  2200.     {
  2201.         *p = ErrVal;
  2202.         return;
  2203.     };
  2204.     *p = ((v1 > 0 || !fmodl(v2, 1)) ? powl(v1, v2) : ErrVal);
  2205. }
  2206.  
  2207. void RacineN(double *&p)
  2208. {
  2209.     double v2 = *p--, v1 = *p;
  2210.     if (v1 == ErrVal || v2 == ErrVal || !v1
  2211.         || v2 * logl(fabsl(v1)) < DBL_MIN_EXP)
  2212.     {
  2213.         *p = ErrVal;
  2214.         return;
  2215.     };
  2216.     if (v2 >= 0)
  2217.     {
  2218.         *p = powl(v2, 1 / v1);
  2219.         return;
  2220.     };
  2221.     *p = ((fabsl(fmodl(v1, 2)) == 1) ? -powl(-v2, 1 / v1) : ErrVal);
  2222. }
  2223.  
  2224. void Puiss10(double *&p)
  2225. {
  2226.     if (fabsl(*p) < sqrtminfloat)
  2227.     {
  2228.         *(--p) = 0;
  2229.         return;
  2230.     };
  2231.     if (*p == ErrVal || fabsl(*p) > DBL_MAX_10_EXP)
  2232.     {
  2233.         *(--p) = ErrVal;
  2234.         return;
  2235.     };
  2236.     if (fabsl(*(--p)) < sqrtminfloat)
  2237.         *p = 0;
  2238.     else if (*p == ErrVal || fabsl(*p) > sqrtmaxfloat)
  2239.     {
  2240.         *p = ErrVal;
  2241.         return;
  2242.     };
  2243.     *p *= pow10l(*(p + 1));
  2244. }
  2245.  
  2246. void ArcTangente2(double *&p)
  2247. {
  2248.     if (*p == ErrVal || fabsl(*p) > inveps)
  2249.     {
  2250.         *(--p) = ErrVal;
  2251.         return;
  2252.     };
  2253.     if (*(--p) == ErrVal || fabsl(*p) > inveps)
  2254.     {
  2255.         *p = ErrVal;
  2256.         return;
  2257.     };
  2258.     *p = (*p || *(p + 1) ? atan2(*p, *(p + 1)) : ErrVal);
  2259. }
  2260.  
  2261. void NextVal(double *&)
  2262. {
  2263. }
  2264.  
  2265. void RFunc(double *&)
  2266. {
  2267. }
  2268.  
  2269. void JuxtF(double *&)
  2270. {
  2271. }
  2272.  
  2273. void Absolu(double *&p)
  2274. {
  2275.     *p = ((*p == ErrVal) ? ErrVal : fabsl(*p));
  2276. }
  2277.  
  2278. void Oppose(double *&p)
  2279. {
  2280.     *p = ((*p == ErrVal) ? ErrVal : -*p);
  2281. }
  2282.  
  2283. void ArcSinus(double *&p)
  2284. {
  2285.     *p = ((*p == ErrVal || fabsl(*p) > 1) ? ErrVal : asinl(*p));
  2286. }
  2287.  
  2288. void ArcCosinus(double *&p)
  2289. {
  2290.     *p = ((*p == ErrVal || fabsl(*p) > 1) ? ErrVal : acosl(*p));
  2291. }
  2292.  
  2293. void ArcTangente(double *&p)
  2294. {
  2295.     *p = ((*p == ErrVal) ? ErrVal : atanl(*p));
  2296. }
  2297.  
  2298. void Logarithme(double *&p)
  2299. {
  2300.     *p = ((*p == ErrVal || *p <= 0) ? ErrVal : logl(*p));
  2301. }
  2302.  
  2303. void Exponentielle(double *&p)
  2304. {
  2305.     *p = ((*p == ErrVal || *p > DBL_MAX_EXP) ? ErrVal : expl(*p));
  2306. }
  2307.  
  2308. void Sinus(double *&p)
  2309. {
  2310.     *p = ((*p == ErrVal || fabsl(*p) > inveps) ? ErrVal : sinl(*p));
  2311. }
  2312.  
  2313. void Tangente(double *&p)
  2314. {
  2315.     *p = ((*p == ErrVal || fabsl(*p) > inveps) ? ErrVal : tanl(*p));
  2316. }
  2317.  
  2318. void Cosinus(double *&p)
  2319. {
  2320.     *p = ((*p == ErrVal || fabsl(*p) > inveps) ? ErrVal : cosl(*p));
  2321. }
  2322.  
  2323. void Racine(double *&p)
  2324. {
  2325.     *p = ((*p == ErrVal || *p > sqrtmaxfloat || *p < 0) ? ErrVal : sqrtl(*p));
  2326. }
  2327.  
  2328. void FonctionError(double *&p)
  2329. {
  2330.     *p = ErrVal;
  2331. }
  2332.  
  2333. inline void ApplyRFunc(PRFunction rf, double *&p)
  2334. {
  2335.     p -= rf->nvars - 1;
  2336.     *p = rf->Val(p);
  2337. }
  2338.  
  2339. double ROperation::Val() const const
  2340. {
  2341.     pfoncld *p1 = pinstr;
  2342.     double **p2 = pvals, *p3 = ppile - 1;
  2343.     PRFunction *p4 = pfuncpile;
  2344.     for (; *p1 != NULL; p1++)
  2345.         if (*p1 == &NextVal)
  2346.             *(++p3) = **(p2++);
  2347.         else if (*p1 == &RFunc)
  2348.             ApplyRFunc(*(p4++), p3);
  2349.         else
  2350.             (**p1) (p3);
  2351.     return *p3;
  2352. }
  2353.  
  2354. void BCDouble(pfoncld * &pf, pfoncld * pf1, pfoncld * pf2,
  2355.               double **&pv, double **pv1, double **pv2,
  2356.               double *&pp, double *pp1, double *pp2,
  2357.               RFunction ** &prf, RFunction ** prf1, RFunction ** prf2,
  2358.               pfoncld f)
  2359. {
  2360.     pfoncld *pf3, *pf4 = pf1;
  2361.     long n1, n2;
  2362.     for (n1 = 0; *pf4 != NULL; pf4++, n1++);
  2363.     for (n2 = 0, pf4 = pf2; *pf4 != NULL; pf4++, n2++);
  2364.     pf = new pfoncld[n1 + n2 + 2];
  2365.     for (pf3 = pf, pf4 = pf1; *pf4 != NULL; pf3++, pf4++)
  2366.         *pf3 = *pf4;
  2367.     for (pf4 = pf2; *pf4 != NULL; pf3++, pf4++)
  2368.         *pf3 = *pf4;
  2369.     *pf3++ = f;
  2370.     *pf3 = NULL;                // delete[]pf1,pf2;
  2371.     double **pv3, **pv4 = pv1;
  2372.     for (n1 = 0; *pv4 != NULL; pv4++, n1++);
  2373.     for (n2 = 0, pv4 = pv2; *pv4 != NULL; pv4++, n2++);
  2374.     pv = new double *[n1 + n2 + 1];
  2375.     for (pv3 = pv, pv4 = pv1; *pv4 != NULL; pv3++, pv4++)
  2376.         *pv3 = *pv4;
  2377.     for (pv4 = pv2; *pv4 != NULL; pv3++, pv4++)
  2378.         *pv3 = *pv4;
  2379.     *pv3 = NULL;                // delete[]pv1,pv2;
  2380.     double *pp3, *pp4 = pp1;
  2381.     for (n1 = 0; *pp4 != ErrVal; pp4++, n1++);
  2382.     for (n2 = 0, pp4 = pp2; *pp4 != ErrVal; pp4++, n2++);
  2383.     pp = new double[n1 + n2 + 1];   // Really need to add and not to take
  2384.                                     // max(n1,n2) in case of Juxt operator
  2385.     for (pp3 = pp, pp4 = pp1; *pp4 != ErrVal; pp3++, pp4++)
  2386.         *pp3 = 0;
  2387.     for (pp4 = pp2; *pp4 != ErrVal; pp3++, pp4++)
  2388.         *pp3 = 0;
  2389.     *pp3 = ErrVal;              // delete[]pp1,pp2;
  2390.     PRFunction *prf3, *prf4 = prf1;
  2391.     for (n1 = 0; *prf4 != NULL; prf4++, n1++);
  2392.     for (n2 = 0, prf4 = prf2; *prf4 != NULL; prf4++, n2++);
  2393.     prf = new PRFunction[n1 + n2 + 1];
  2394.     for (prf3 = prf, prf4 = prf1; *prf4 != NULL; prf3++, prf4++)
  2395.         *prf3 = *prf4;
  2396.     for (prf4 = prf2; *prf4 != NULL; prf3++, prf4++)
  2397.         *prf3 = *prf4;
  2398.     *prf3 = NULL;               // delete[]prf1,prf2;
  2399. }
  2400.  
  2401. void BCSimple(pfoncld * &pf, pfoncld * pf1, double **&pv, double **pv1,
  2402.               double *&pp, double *pp1, RFunction ** &prf, RFunction ** prf1,
  2403.               pfoncld f)
  2404. {
  2405.     pfoncld *pf3, *pf4 = pf1;
  2406.     long n;
  2407.     for (n = 0; *pf4 != NULL; pf4++, n++);
  2408.     pf = new pfoncld[n + 2];
  2409.     for (pf4 = pf1, pf3 = pf; *pf4 != NULL; pf3++, pf4++)
  2410.         *pf3 = *pf4;
  2411.     *pf3++ = f;
  2412.     *pf3 = NULL;                // delete[]pf1;
  2413.     double **pv3, **pv4 = pv1;
  2414.     for (n = 0; *pv4 != NULL; pv4++, n++);
  2415.     pv = new double *[n + 1];
  2416.     for (pv3 = pv, pv4 = pv1; *pv4 != NULL; pv3++, pv4++)
  2417.         *pv3 = *pv4;
  2418.     *pv3 = NULL;                // delete[]pv1;
  2419.     double *pp3, *pp4 = pp1;
  2420.     for (n = 0; *pp4 != ErrVal; pp4++, n++);
  2421.     pp = new double[n + 1];
  2422.     for (pp3 = pp, pp4 = pp1; *pp4 != ErrVal; pp3++, pp4++)
  2423.         *pp3 = 0;
  2424.     *pp3 = ErrVal;              // delete[]pp1;
  2425.     RFunction **prf3, **prf4 = prf1;
  2426.     for (n = 0; *prf4 != NULL; prf4++, n++);
  2427.     prf = new RFunction *[n + 1];
  2428.     for (prf3 = prf, prf4 = prf1; *prf4 != NULL; prf3++, prf4++)
  2429.         *prf3 = *prf4;
  2430.     *prf3 = NULL;               // delete[]prf1;
  2431. }
  2432.  
  2433. void BCFun(pfoncld * &pf, pfoncld * pf1, double **&pv, double **pv1,
  2434.            double *&pp, double *pp1, RFunction ** &prf, RFunction ** prf1,
  2435.            PRFunction rf)
  2436. {
  2437.     pfoncld *pf3, *pf4 = pf1;
  2438.     long n;
  2439.     for (n = 0; *pf4 != NULL; pf4++, n++);
  2440.     pf = new pfoncld[n + 2];
  2441.     for (pf4 = pf1, pf3 = pf; *pf4 != NULL; pf3++, pf4++)
  2442.         *pf3 = *pf4;
  2443.     *pf3++ = &RFunc;
  2444.     *pf3 = NULL;                // delete[]pf1;
  2445.     double **pv3, **pv4 = pv1;
  2446.     for (n = 0; *pv4 != NULL; pv4++, n++);
  2447.     pv = new double *[n + 1];
  2448.     for (pv3 = pv, pv4 = pv1; *pv4 != NULL; pv3++, pv4++)
  2449.         *pv3 = *pv4;
  2450.     *pv3 = NULL;                // delete[]pv1;
  2451.     double *pp3, *pp4 = pp1;
  2452.     for (n = 0; *pp4 != ErrVal; pp4++, n++);
  2453.     pp = new double[n + 1];
  2454.     for (pp3 = pp, pp4 = pp1; *pp4 != ErrVal; pp3++, pp4++)
  2455.         *pp3 = 0;
  2456.     *pp3 = ErrVal;              // delete[]pp1;
  2457.     PRFunction *prf3, *prf4 = prf1;
  2458.     for (n = 0; *prf4 != NULL; prf4++, n++);
  2459.     prf = new PRFunction[n + 2];
  2460.     for (prf4 = prf1, prf3 = prf; *prf4 != NULL; prf3++, prf4++)
  2461.         *prf3 = *prf4;
  2462.     *prf3++ = rf;
  2463.     *prf3 = NULL;               // delete[]pf1;
  2464. }
  2465.  
  2466. void ROperation::BuildCode()
  2467. {
  2468.     // if(mmb1!=NULL)mmb1->BuildCode();if(mmb2!=NULL)mmb2->BuildCode();
  2469.     if (pinstr != NULL)
  2470.     {
  2471.         delete[]pinstr;
  2472.         pinstr = NULL;
  2473.     }
  2474.     if (pvals != NULL)
  2475.     {
  2476.         delete[]pvals;
  2477.         pvals = NULL;
  2478.     }                           // does not delete pvals[0] in case it was to
  2479.                                 // be deleted... (no way to know)
  2480.     if (ppile != NULL)
  2481.     {
  2482.         delete[]ppile;
  2483.         ppile = NULL;
  2484.     }
  2485.     if (pfuncpile != NULL)
  2486.     {
  2487.         delete[]pfuncpile;
  2488.         pfuncpile = NULL;
  2489.     }
  2490.     switch (op)
  2491.     {
  2492.     case ErrOp:
  2493.         pinstr = new pfoncld[2];
  2494.         pinstr[0] = &NextVal;
  2495.         pinstr[1] = NULL;
  2496.         pvals = new double *[2];
  2497.         pvals[0] = new double (ErrVal);
  2498.         pvals[1] = NULL;
  2499.         ppile = new double[2];
  2500.         ppile[0] = 0;
  2501.         ppile[1] = ErrVal;
  2502.         pfuncpile = new RFunction *[1];
  2503.         pfuncpile[0] = NULL;
  2504.         break;
  2505.     case Num:
  2506.         pinstr = new pfoncld[2];
  2507.         pinstr[0] = &NextVal;
  2508.         pinstr[1] = NULL;
  2509.         pvals = new double *[2];
  2510.         pvals[0] = new double (ValC);
  2511.         pvals[1] = NULL;
  2512.         ppile = new double[2];
  2513.         ppile[0] = 0;
  2514.         ppile[1] = ErrVal;
  2515.         pfuncpile = new RFunction *[1];
  2516.         pfuncpile[0] = NULL;
  2517.         break;
  2518.     case Var:
  2519.         pinstr = new pfoncld[2];
  2520.         pinstr[0] = &NextVal;
  2521.         pinstr[1] = NULL;
  2522.         pvals = new double *[2];
  2523.         pvals[0] = pvarval;
  2524.         pvals[1] = NULL;
  2525.         ppile = new double[2];
  2526.         ppile[0] = 0;
  2527.         ppile[1] = ErrVal;
  2528.         pfuncpile = new RFunction *[1];
  2529.         pfuncpile[0] = NULL;
  2530.         break;
  2531.     case Juxt:
  2532.         BCDouble(pinstr, mmb1->pinstr, mmb2->pinstr,
  2533.                  pvals, mmb1->pvals, mmb2->pvals, ppile, mmb1->ppile,
  2534.                  mmb2->ppile, pfuncpile, mmb1->pfuncpile, mmb2->pfuncpile,
  2535.                  &JuxtF);
  2536.         break;
  2537.     case Add:
  2538.         BCDouble(pinstr, mmb1->pinstr, mmb2->pinstr,
  2539.                  pvals, mmb1->pvals, mmb2->pvals, ppile, mmb1->ppile,
  2540.                  mmb2->ppile, pfuncpile, mmb1->pfuncpile, mmb2->pfuncpile,
  2541.                  &Addition);
  2542.         break;
  2543.     case Sub:
  2544.         BCDouble(pinstr, mmb1->pinstr, mmb2->pinstr,
  2545.                  pvals, mmb1->pvals, mmb2->pvals, ppile, mmb1->ppile,
  2546.                  mmb2->ppile, pfuncpile, mmb1->pfuncpile, mmb2->pfuncpile,
  2547.                  &Soustraction);
  2548.         break;
  2549.     case Mult:
  2550.         BCDouble(pinstr, mmb1->pinstr, mmb2->pinstr,
  2551.                  pvals, mmb1->pvals, mmb2->pvals, ppile, mmb1->ppile,
  2552.                  mmb2->ppile, pfuncpile, mmb1->pfuncpile, mmb2->pfuncpile,
  2553.                  &Multiplication);
  2554.         break;
  2555.     case Div:
  2556.         BCDouble(pinstr, mmb1->pinstr, mmb2->pinstr,
  2557.                  pvals, mmb1->pvals, mmb2->pvals, ppile, mmb1->ppile,
  2558.                  mmb2->ppile, pfuncpile, mmb1->pfuncpile, mmb2->pfuncpile,
  2559.                  &Division);
  2560.         break;
  2561.     case Pow:
  2562.         BCDouble(pinstr, mmb1->pinstr, mmb2->pinstr,
  2563.                  pvals, mmb1->pvals, mmb2->pvals, ppile, mmb1->ppile,
  2564.                  mmb2->ppile, pfuncpile, mmb1->pfuncpile, mmb2->pfuncpile,
  2565.                  &Puissance);
  2566.         break;
  2567.     case NthRoot:
  2568.         BCDouble(pinstr, mmb1->pinstr, mmb2->pinstr,
  2569.                  pvals, mmb1->pvals, mmb2->pvals, ppile, mmb1->ppile,
  2570.                  mmb2->ppile, pfuncpile, mmb1->pfuncpile, mmb2->pfuncpile,
  2571.                  &RacineN);
  2572.         break;
  2573.     case E10:
  2574.         BCDouble(pinstr, mmb1->pinstr, mmb2->pinstr,
  2575.                  pvals, mmb1->pvals, mmb2->pvals, ppile, mmb1->ppile,
  2576.                  mmb2->ppile, pfuncpile, mmb1->pfuncpile, mmb2->pfuncpile,
  2577.                  &Puiss10);
  2578.         break;
  2579.     case Opp:
  2580.         BCSimple(pinstr, mmb2->pinstr, pvals, mmb2->pvals,
  2581.                  ppile, mmb2->ppile, pfuncpile, mmb2->pfuncpile, &Oppose);
  2582.         break;
  2583.     case Sin:
  2584.         BCSimple(pinstr, mmb2->pinstr, pvals, mmb2->pvals,
  2585.                  ppile, mmb2->ppile, pfuncpile, mmb2->pfuncpile, &Sinus);
  2586.         break;
  2587.     case Sqrt:
  2588.         BCSimple(pinstr, mmb2->pinstr, pvals, mmb2->pvals,
  2589.                  ppile, mmb2->ppile, pfuncpile, mmb2->pfuncpile, &Racine);
  2590.         break;
  2591.     case Ln:
  2592.         BCSimple(pinstr, mmb2->pinstr, pvals, mmb2->pvals,
  2593.                  ppile, mmb2->ppile, pfuncpile, mmb2->pfuncpile, &Logarithme);
  2594.         break;
  2595.     case Exp:
  2596.         BCSimple(pinstr, mmb2->pinstr, pvals, mmb2->pvals,
  2597.                  ppile, mmb2->ppile, pfuncpile, mmb2->pfuncpile,
  2598.                  &Exponentielle);
  2599.         break;
  2600.     case Cos:
  2601.         BCSimple(pinstr, mmb2->pinstr, pvals, mmb2->pvals,
  2602.                  ppile, mmb2->ppile, pfuncpile, mmb2->pfuncpile, &Cosinus);
  2603.         break;
  2604.     case Tg:
  2605.         BCSimple(pinstr, mmb2->pinstr, pvals, mmb2->pvals,
  2606.                  ppile, mmb2->ppile, pfuncpile, mmb2->pfuncpile, &Tangente);
  2607.         break;
  2608.     case Atan:
  2609.         BCSimple(pinstr, mmb2->pinstr, pvals, mmb2->pvals,
  2610.                  ppile, mmb2->ppile, pfuncpile, mmb2->pfuncpile,
  2611.                  (mmb2->NMembers() > 1 ? &ArcTangente2 : &ArcTangente));
  2612.         break;
  2613.     case Asin:
  2614.         BCSimple(pinstr, mmb2->pinstr, pvals, mmb2->pvals,
  2615.                  ppile, mmb2->ppile, pfuncpile, mmb2->pfuncpile, &ArcSinus);
  2616.         break;
  2617.     case Acos:
  2618.         BCSimple(pinstr, mmb2->pinstr, pvals, mmb2->pvals,
  2619.                  ppile, mmb2->ppile, pfuncpile, mmb2->pfuncpile, &ArcCosinus);
  2620.         break;
  2621.     case Abs:
  2622.         BCSimple(pinstr, mmb2->pinstr, pvals, mmb2->pvals,
  2623.                  ppile, mmb2->ppile, pfuncpile, mmb2->pfuncpile, &Absolu);
  2624.         break;
  2625.     case Fun:
  2626.         BCFun(pinstr, mmb2->pinstr, pvals, mmb2->pvals, ppile,
  2627.               mmb2->ppile, pfuncpile, mmb2->pfuncpile, pfunc);
  2628.         break;
  2629.     default:
  2630.         BCSimple(pinstr, mmb2->pinstr, pvals, mmb2->pvals,
  2631.                  ppile, mmb2->ppile, pfuncpile, mmb2->pfuncpile,
  2632.                  &FonctionError);
  2633.     }
  2634. }
  2635.  
  2636. int main()
  2637. {
  2638.     int n;
  2639.     cin >> n;
  2640.     for (int i = 0; i < n; i++)
  2641.     {
  2642.         double x;
  2643.         double y;
  2644.         char s[500] = "";
  2645.  
  2646.         cin >> s;
  2647.         cin >> x >> y;
  2648.  
  2649.         RVar xvar("x", &x);
  2650.         RVar yvar("y", &y);
  2651.         RVar *vararray2[2];
  2652.         vararray2[0] = &xvar;
  2653.         vararray2[1] = &yvar;
  2654.  
  2655.         RVar *vararray[1];
  2656.         vararray[0] = &xvar;
  2657.         ROperation op(s, 1, vararray);
  2658.         RFunction f(op, &xvar);
  2659.         f.SetName("f");
  2660.  
  2661.         RFunction *funcarray[1];
  2662.         funcarray[0] = &f;
  2663.         ROperation op2((char *)s, 2, vararray2, 1, funcarray);
  2664.  
  2665.         double wynik;
  2666.         wynik = op2.Val();
  2667.  
  2668.         cout << fixed << setprecision(2) << wynik;
  2669.     }
  2670.     return 0;
  2671. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement