home *** CD-ROM | disk | FTP | other *** search
/ APDL Public Domain 1 / APDL_PD1A.iso / program / language / icon / Source / Iconx / C / Oarith < prev    next >
Encoding:
Text File  |  1990-07-19  |  15.4 KB  |  739 lines

  1. /*
  2.  * File: oarith.c
  3.  *  Contents: divide, minus, mod, mult, neg, number, plus, powr
  4.  */
  5.  
  6. #include <math.h>
  7. #include "../h/config.h"
  8. #include "../h/rt.h"
  9. #include "rproto.h"
  10.  
  11.  
  12. #ifdef SUN
  13. #include <signal.h>
  14. #endif                    /* SUN */
  15.  
  16. int over_flow;
  17.  
  18. /*
  19.  * x / y - divide y into x.
  20.  */
  21.  
  22. OpDcl(divide,2,"/")
  23.    {
  24.    register int t1, t2;
  25.    double r1, r2;
  26.  
  27.    /*
  28.     * Arg1 and Arg2 must be numeric.
  29.     */
  30.    if ((t1 = cvnum(&Arg1)) == CvtFail)
  31.       RunErr(102, &Arg1);
  32.    if ((t2 = cvnum(&Arg2)) == CvtFail) 
  33.       RunErr(102, &Arg2);
  34.  
  35.    if (t1 == T_Integer && t2 == T_Integer) {
  36.       /*
  37.        * Arg1 and Arg2 are both integers, just divide them and return the
  38.        * result.
  39.        */
  40.       if (IntVal(Arg2) == 0L) 
  41.          RunErr(201, &Arg2);
  42.  
  43. #if MSDOS && LATTICE
  44.       {
  45.       long i, j;
  46.       i = IntVal(Arg1);
  47.       j = i / IntVal(Arg2);
  48.       MakeInt(j, &Arg0);
  49.       }
  50. #else                    /* MSDOS && LATTICE */
  51.        MakeInt(IntVal(Arg1) / IntVal(Arg2), &Arg0);
  52. #endif                    /* MSDOS && LATTICE */
  53.  
  54.       }
  55.    else if (t1 == T_Real || t2 == T_Real) {
  56.       /*
  57.        * Either Arg1 or Arg2 or both is real, convert the real values to
  58.        *  integers, divide them, and return the result.
  59.        */
  60.       if (t1 != T_Real) {
  61.  
  62. #ifdef LargeInts
  63.          if (t1 == T_Bignum)
  64.         r1 = bigtoreal(&Arg1);
  65.      else
  66. #endif                    /* LargeInts */
  67.  
  68.             r1 = IntVal(Arg1);
  69.          }
  70.       else
  71.      r1 = BlkLoc(Arg1)->realblk.realval;
  72.  
  73.       if (t2 != T_Real) {
  74.  
  75. #ifdef LargeInts
  76.      if (t2 == T_Bignum)
  77.         r2 = bigtoreal(&Arg2);
  78.      else
  79. #endif                    /* LargeInts */
  80.  
  81.             r2 = IntVal(Arg2);
  82.          }
  83.       else
  84.      r2 = BlkLoc(Arg2)->realblk.realval;
  85.  
  86.       if (r2 == 0.0) 
  87.          RunErr(-204, NULL);
  88.  
  89.       if (makereal(r1 / r2, &Arg0) == Error) 
  90.          RunErr(0, NULL);
  91.  
  92. #ifdef SUN
  93.       if (((struct b_real *)BlkLoc(Arg0))->realval == HUGE)
  94.          kill(getpid(),SIGFPE);
  95. #endif                    /* SUN */
  96.  
  97.       }
  98.  
  99. #ifdef LargeInts
  100.    else {
  101.       /*
  102.        * Neither Arg1 or Arg2 are real and at least one is a large int.
  103.        */
  104.       if (bigdiv(&Arg1, &Arg2, &Arg0) == Error)  /* alcbignum failed */
  105.      RunErr(0, NULL);
  106.       }
  107. #endif                    /* LargeInts */
  108.  
  109.    Return;
  110.    }
  111.  
  112.  
  113. /*
  114.  * x - y - subtract y from x.
  115.  */
  116.  
  117. OpDcl(minus,2,"-")
  118.    {
  119.    register int t1, t2;
  120.    double r1, r2;
  121.  
  122.    /*
  123.     * x and y must be numeric.  Save the cvnum return values for later use.
  124.     */
  125.    if ((t1 = cvnum(&Arg1)) == CvtFail) 
  126.       RunErr(102, &Arg1);
  127.    if ((t2 = cvnum(&Arg2)) == CvtFail) 
  128.       RunErr(102, &Arg2);
  129.  
  130.    if (t1 == T_Integer && t2 == T_Integer) {
  131.       /*
  132.        * Both x and y are integers.  Perform integer subtraction and place
  133.        *  the result in Arg0 as the return value.
  134.        */
  135.  
  136.       MakeInt(sub(IntVal(Arg1), IntVal(Arg2)), &Arg0);
  137.       if (over_flow)
  138.  
  139. #ifdef LargeInts
  140.      if (bigsub(&Arg1, &Arg2, &Arg0) == Error)  /* alcbignum failed */
  141.         RunErr(0, NULL);
  142. #else                    /* LargeInts */
  143.          RunErr(-203, NULL);
  144. #endif                    /* LargeInts */
  145.  
  146.       }
  147.    else if (t1 == T_Real || t2 == T_Real) {
  148.       /*
  149.        * Either x or y is real, convert the other to a real, perform
  150.        *  the subtraction and place the result in Arg0 as the return value.
  151.        */
  152.       if (t1 != T_Real) {
  153.  
  154. #ifdef LargeInts
  155.          if (t1 == T_Bignum)
  156.         r1 = bigtoreal(&Arg1);
  157.      else
  158. #endif                    /* LargeInts */
  159.  
  160.             r1 = IntVal(Arg1);
  161.          }
  162.       else
  163.      r1 = BlkLoc(Arg1)->realblk.realval;
  164.  
  165.       if (t2 != T_Real) {
  166.  
  167. #ifdef LargeInts
  168.      if (t2 == T_Bignum)
  169.         r2 = bigtoreal(&Arg2);
  170.      else
  171. #endif                    /* LargeInts */
  172.  
  173.             r2 = IntVal(Arg2);
  174.          }
  175.       else
  176.      r2 = BlkLoc(Arg2)->realblk.realval;
  177.  
  178. #ifdef  RTACIS
  179.       {
  180.       double rtbug_temporary;    /* bug with "-" arithmetic as parameter */
  181.       rtbug_temporary = r1 - r2;    
  182.       if (makereal(rtbug_temporary, &Arg0) == Error) 
  183.          RunErr(0, NULL);
  184. #else                    /* RTACIS */
  185.       if (makereal(r1 - r2, &Arg0) == Error) 
  186.          RunErr(0, NULL);
  187. #endif                    /* RTACIS */
  188.  
  189.       }
  190.  
  191. #ifdef LargeInts
  192.    else {
  193.       /*
  194.        * Neither Arg1 or Arg2 are real and at least one is a large int.
  195.        */
  196.       if (bigsub(&Arg1, &Arg2, &Arg0) == Error)  /* alcbignum failed */
  197.      RunErr(0, NULL);
  198.       }
  199. #endif                    /* LargeInts */
  200.  
  201.    Return;
  202.    }
  203.  
  204.  
  205. /*
  206.  * x % y - take remainder of x / y.
  207.  */
  208.  
  209. OpDcl(mod,2,"%")
  210.    {
  211.    register int t1, t2;
  212.    long int_rslt;
  213.    double r1, r2, real_rslt;
  214.  
  215.    /*
  216.     * x and y must be numeric.  Save the cvnum return values for later use.
  217.     */
  218.    if ((t1 = cvnum(&Arg1)) == CvtFail) 
  219.       RunErr(102, &Arg1);
  220.    if ((t2 = cvnum(&Arg2)) == CvtFail) 
  221.       RunErr(102, &Arg2);
  222.  
  223.    if (t1 == T_Integer && t2 == T_Integer) {
  224.       /*
  225.        * Both x and y are integers.  If y is 0, generate an error because
  226.        *  it's divide by 0.  Otherwise, just return the modulus of the
  227.        *  two arguments.
  228.        */
  229.       if (IntVal(Arg2) == 0L) 
  230.          RunErr(202, &Arg2);
  231.  
  232. #if MSDOS && LATTICE
  233.       {
  234.       long i;
  235.       i = IntVal(Arg1);
  236.       int_rslt = i % IntVal(Arg2);
  237.       }
  238. #else                    /* MSDOS && LATTICE */
  239.        int_rslt = IntVal(Arg1) % IntVal(Arg2);
  240. #endif                    /* MSDOS && LATTICE */
  241.  
  242.       /*
  243.        * The sign of the result must match that of n1.
  244.        */
  245.       if (IntVal(Arg1) < 0) {
  246.          if (int_rslt > 0)
  247.             int_rslt -= Abs(IntVal(Arg2));
  248.          }
  249.       else if (int_rslt < 0)
  250.          int_rslt += Abs(IntVal(Arg2));
  251.       MakeInt(int_rslt, &Arg0);
  252.       }
  253.    else if (t1 == T_Real || t2 == T_Real) {
  254.       /*
  255.        * Either x or y is real, convert the other to a real, get
  256.        *  the modulus, convert the result to an integer and place it
  257.        *  in Arg0 as the return value.
  258.        */
  259.       if (t1 != T_Real) {
  260.  
  261. #ifdef LargeInts
  262.      if (t1 == T_Bignum)
  263.         r1 = bigtoreal(&Arg1);
  264.      else
  265. #endif                    /* LargeInts */
  266.  
  267.             r1 = IntVal(Arg1);
  268.          }
  269.       else
  270.      r1 = BlkLoc(Arg1)->realblk.realval;
  271.  
  272.       if (t2 != T_Real) {
  273.  
  274. #ifdef LargeInts
  275.      if (t2 == T_Bignum)
  276.         r2 = bigtoreal(&Arg2);
  277.      else
  278. #endif                    /* LargeInts */
  279.  
  280.             r2 = IntVal(Arg2);
  281.          }
  282.       else
  283.      r2 = BlkLoc(Arg2)->realblk.realval;
  284.  
  285.       real_rslt = r1 - r2 * (int)(r1 / r2);
  286.       /*
  287.        * The sign of the result must match that of n1.
  288.        */
  289.       if (r1 < 0.0) {
  290.          if (real_rslt > 0.0)
  291.             real_rslt -= fabs(r2);
  292.          }
  293.       else if (real_rslt < 0.0)
  294.          real_rslt += fabs(r2);
  295.       if (makereal(real_rslt, &Arg0) == Error) 
  296.          RunErr(0, NULL);
  297.       }
  298.  
  299. #ifdef LargeInts
  300.    else {
  301.       /*
  302.        * Neither Arg1 or Arg2 are real and at least one is a large int.
  303.        */
  304.       if (bigmod(&Arg1, &Arg2, &Arg0) == Error)  /* alcbignum failed */
  305.      RunErr(0, NULL);
  306.       }
  307. #endif                    /* LargeInts */
  308.  
  309.    Return;
  310.    }
  311.  
  312.  
  313. /*
  314.  * x * y - multiply x and y.
  315.  */
  316.  
  317. OpDcl(mult,2,"*")
  318.    {
  319.    register int t1, t2;
  320.    double r1, r2;
  321.  
  322.    /*
  323.     * Arg1 and Arg2 must be numeric.  Save the cvnum return values for later
  324.     *  use.
  325.     */
  326.    if ((t1 = cvnum(&Arg1)) == CvtFail) 
  327.       RunErr(102, &Arg1);
  328.    if ((t2 = cvnum(&Arg2)) == CvtFail) 
  329.       RunErr(102, &Arg2);
  330.  
  331.    if (t1 == T_Integer && t2 == T_Integer) {
  332.       /*
  333.        * Both Arg1 and Arg2 are integers.  Perform the multiplication and
  334.        *  and place the result in Arg0 as the return value.
  335.        */
  336.  
  337.       MakeInt(mul(IntVal(Arg1), IntVal(Arg2)), &Arg0);
  338.       if (over_flow)
  339. #ifdef LargeInts
  340.      if (bigmul(&Arg1, &Arg2, &Arg0) == Error)  /* alcbignum failed */
  341.         RunErr(0, NULL);
  342. #else                    /* LargeInts */
  343.          RunErr(-203, NULL);
  344. #endif                    /* LargeInts */
  345.       }
  346.    else if (t1 == T_Real || t2 == T_Real) {
  347.       /*
  348.        * Either Arg1 or Arg2 is real, convert the other to a real, perform
  349.        *  the subtraction and place the result in Arg0 as the return value.
  350.        */
  351.       if (t1 != T_Real) {
  352.  
  353. #ifdef LargeInts
  354.      if (t1 == T_Bignum)
  355.         r1 = bigtoreal(&Arg1);
  356.      else
  357. #endif                    /* LargeInts */
  358.  
  359.             r1 = IntVal(Arg1);
  360.          }
  361.       else
  362.      r1 = BlkLoc(Arg1)->realblk.realval;
  363.  
  364.       if (t2 != T_Real) {
  365.  
  366. #ifdef LargeInts
  367.      if (t2 == T_Bignum)
  368.         r2  = bigtoreal(&Arg2);
  369.      else
  370. #endif                    /* LargeInts */
  371.  
  372.             r2 = IntVal(Arg2);
  373.          }
  374.       else
  375.      r2 = BlkLoc(Arg2)->realblk.realval;
  376.  
  377.       if (makereal(r1 * r2, &Arg0) == Error) 
  378.          RunErr(0, NULL);
  379.       }
  380.  
  381. #ifdef LargeInts
  382.    else {
  383.       /*
  384.        * Neither Arg1 or Arg2 are real and at least one is a large int.
  385.        */
  386.       if (bigmul(&Arg1, &Arg2, &Arg0) == Error)  /* alcbignum failed */
  387.      RunErr(0, NULL);
  388.       }
  389. #endif                    /* LargeInts */
  390.  
  391.    Return;
  392.    }
  393.  
  394. /*
  395.  * -x - negate x.
  396.  */
  397.  
  398. OpDcl(neg,1,"-")
  399.    {
  400.  
  401.    /*
  402.     * Arg1 must be numeric.
  403.     */
  404.    switch (cvnum(&Arg1)) {
  405.  
  406.       case T_Integer:
  407.          /*
  408.           * If Arg1 is an integer, check for overflow by negating it and
  409.           *  seeing if the negation didn't "work".  Use MakeInt to
  410.           *  construct the return value.
  411.           */
  412.  
  413.      MakeInt(neg(IntVal(Arg1)), &Arg0);
  414.          if (over_flow)
  415.  
  416. #ifdef LargeInts
  417.         if (bigneg(&Arg1, &Arg0) == Error)  /* alcbignum failed */
  418.            RunErr(0, NULL);
  419. #else                    /* LargeInts */
  420.          RunErr(-203, &Arg1);
  421. #endif                    /* LargeInts */
  422.  
  423.          break;
  424.  
  425. #ifdef LargeInts
  426.       case T_Bignum:
  427.      if (cpbignum(&Arg1, &Arg0) == Error)  /* alcbignum failed */
  428.         RunErr(0, NULL);
  429.      BlkLoc(Arg0)->bignumblk.sign ^= 1;
  430.      break;
  431. #endif                    /* LargeInts */
  432.  
  433.       case T_Real:
  434.          /*
  435.           * Arg1 is real, just negate it and use makereal to construct the
  436.           *  return value.
  437.           */
  438.  
  439. #ifdef RTACIS
  440.          { 
  441.          double rtbug_temporary;        /* bug with "-" as parameter */
  442.          rtbug_temporary = -BlkLoc(Arg1)->realblk.realval;
  443.          if (makereal(rtbug_temporary, &Arg0) == Error) 
  444.             RunErr(0, NULL);
  445.          }
  446. #else                    /* RTACIS */
  447.          if (makereal(-BlkLoc(Arg1)->realblk.realval, &Arg0) == Error) 
  448.             RunErr(0, NULL);
  449. #endif                    /* RTACIS */
  450.  
  451.          break;
  452.  
  453.       default:
  454.          /*
  455.           * Arg1 is not numeric.
  456.           */
  457.          RunErr(102, &Arg1);
  458.       }
  459.    Return;
  460.    }
  461.  
  462. /*
  463.  * +x - convert x to numeric type.
  464.  *  Operational definition: generate runerr if x is not numeric.
  465.  */
  466.  
  467. OpDcl(number,1,"+")
  468.    {
  469.  
  470.    switch (cvnum(&Arg1)) {
  471.  
  472.       case T_Integer:
  473.  
  474. #ifdef LargeInts
  475.       case T_Bignum:
  476. #endif                    /* LargeInts */
  477.  
  478.       case T_Real:
  479.      Arg0 = Arg1;
  480.          break;
  481.  
  482.       default:
  483.          RunErr(102, &Arg1);
  484.       }
  485.    Return;
  486.    }
  487.  
  488. /*
  489.  * x + y - add x and y.
  490.  */
  491.  
  492. OpDcl(plus,2,"+")
  493.    {
  494.    register int t1, t2;
  495.    double r1, r2;
  496.  
  497.    /*
  498.     * Arg1 and Arg2 must be numeric.  Save the cvnum return values for later
  499.     *  use.
  500.     */
  501.    if ((t1 = cvnum(&Arg1)) == CvtFail) 
  502.       RunErr(102, &Arg1);
  503.    if ((t2 = cvnum(&Arg2)) == CvtFail) 
  504.       RunErr(102, &Arg2);
  505.  
  506.    if (t1 == T_Integer && t2 == T_Integer) {
  507.       /*
  508.        * Both Arg1 and Arg2 are integers.  Perform integer addition and plcae
  509.        *  the result in Arg0 as the return value.
  510.        */
  511.  
  512.       MakeInt(add(IntVal(Arg1), IntVal(Arg2)), &Arg0);
  513.       if (over_flow)
  514.  
  515. #ifdef LargeInts
  516.      if (bigadd(&Arg1, &Arg2, &Arg0) == Error)  /* alcbignum failed */
  517.         RunErr(0, NULL);
  518. #else                    /* LargeInts */
  519.          RunErr(-203, NULL);
  520. #endif                    /* LargeInts */
  521.  
  522.       }
  523.    else if (t1 == T_Real || t2 == T_Real) {
  524.       /*
  525.        * Either Arg1 or Arg2 is real, convert the other to a real, perform
  526.        *  the addition and place the result in Arg0 as the return value.
  527.        */
  528.       if (t1 != T_Real) {
  529.  
  530. #ifdef LargeInts
  531.      if (t1 == T_Bignum)
  532.         r1 = bigtoreal(&Arg1);
  533.      else
  534. #endif                    /* LargeInts */
  535.  
  536.             r1 = IntVal(Arg1);
  537.          }
  538.       else
  539.      r1 = BlkLoc(Arg1)->realblk.realval;
  540.  
  541.       if (t2 != T_Real) {
  542.  
  543. #ifdef LargeInts
  544.      if (t2 == T_Bignum)
  545.         r2 = bigtoreal(&Arg2);
  546.      else
  547. #endif                    /* LargeInts */
  548.  
  549.             r2 = IntVal(Arg2);
  550.          }
  551.       else
  552.      r2 = BlkLoc(Arg2)->realblk.realval;
  553.  
  554.       if (makereal(r1 + r2, &Arg0) == Error) 
  555.          RunErr(0, NULL);
  556.       }
  557.  
  558. #ifdef LargeInts
  559.    else {
  560.       /*
  561.        * Neither Arg1 or Arg2 are real and at least one is a large int.
  562.        */
  563.       if (bigadd(&Arg1, &Arg2, &Arg0) == Error)  /* alcbignum failed */
  564.      RunErr(0, NULL);
  565.       }
  566. #endif                    /* LargeInts */
  567.  
  568.    Return;
  569.    }
  570.  
  571. /*
  572.  * x ^ y - raise x to the y power.
  573.  */
  574.  
  575. #if AMIGA
  576. #if AZTEC_C
  577. #ifndef RTACIS
  578. #define RTACIS
  579. #define AZTECHACK
  580. #endif                    /* RTACIS */
  581. #endif                    /* AZTEC_C */
  582. #endif                    /* AMIGA */
  583.  
  584. OpDcl(powr,2,"^")
  585.    {
  586.    register int t1, t2;
  587.    double r1, r2;
  588.  
  589.    /*
  590.     * Arg1 and Arg2 must be numeric.  Save the cvnum return values for later
  591.     *  use.
  592.     */
  593.    if ((t1 = cvnum(&Arg1)) == CvtFail) 
  594.       RunErr(102, &Arg1);
  595.    if ((t2 = cvnum(&Arg2)) == CvtFail) 
  596.       RunErr(102, &Arg2);
  597.  
  598.    if (t1 == T_Integer && t2 == T_Integer) {
  599.       /*
  600.        * Both Arg1 and Arg2 are integers.  Perform integer exponentiation
  601.        *  and place the result in Arg0 as the return value.
  602.        */
  603.  
  604. #ifdef LargeInts
  605.       if (bigpow(&Arg1, &Arg2, &Arg0) == Error)  /* alcbignum failed */
  606.      RunErr(0, NULL);
  607. #else                    /* LargeInts */
  608.       MakeInt(ipow(IntVal(Arg1), IntVal(Arg2)), &Arg0);
  609.       if (over_flow)
  610.          RunErr(-203, NULL);
  611. #endif                    /* LargeInts */
  612.  
  613.       }
  614.    else if (t1 == T_Real || t2 == T_Real) {
  615.       /*
  616.        * Either x or y is real, convert the other to a real, perform
  617.        *  real exponentiation and place the result in Arg0 as the
  618.        *  return value.
  619.        */
  620.       if (t1 != T_Real) {
  621.  
  622. #ifdef LargeInts
  623.      if (t1 == T_Bignum)
  624.         r1 = bigtoreal(&Arg1);
  625.      else
  626. #endif                    /* LargeInts */
  627.  
  628.             r1 = IntVal(Arg1);
  629.          }
  630.       else
  631.      r1 = BlkLoc(Arg1)->realblk.realval;
  632.  
  633.       if (t2 != T_Real) {
  634.  
  635. #ifdef LargeInts
  636.      if (t2 == T_Bignum)
  637.         r2 = bigtoreal(&Arg2);
  638.      else
  639. #endif                    /* LargeInts */
  640.  
  641.             r2 = IntVal(Arg2);
  642.          }
  643.       else
  644.      r2 = BlkLoc(Arg2)->realblk.realval;
  645.  
  646.       if (r1 == 0.0 && r2 <= 0.0) 
  647.          /*
  648.           * Tried to raise zero to a negative power.
  649.           */
  650.          RunErr(-204, NULL);
  651.       if (r1 < 0.0 && t2 == T_Real) 
  652.          /*
  653.           * Tried to raise a negative number to a real power.
  654.           */
  655.          RunErr(-206, NULL);
  656.  
  657. #undef POWBUG
  658. #ifdef RTACIS
  659. #define POWBUG
  660. #endif                    /* RTACIS */
  661. #ifndef POWBUG
  662. #ifdef CRAY
  663. #define POWBUG
  664. #endif                    /* CRAY */
  665. #endif                    /* POSBUG */
  666.  
  667. #ifdef POWBUG
  668.       {
  669.        double rtbug_temporary;        /* bug in pow routine for negative x */
  670.  
  671.        if ((r1 < 0.0) && /* integral? */ (((double)((long int)r2)) == r2)) {
  672.           rtbug_temporary = -r1; 
  673.  
  674.           /*
  675.            * The following is correct only if the exponent is odd.
  676.            *  If the exponent is even, it should be
  677.            *
  678.            *      pow(-rtbug_temporary,r2);
  679.            *
  680.            */
  681.           rtbug_temporary = -pow(rtbug_temporary, r2); 
  682.           } 
  683.        else
  684.       rtbug_temporary = pow(r1, r2);
  685.        if (makereal(rtbug_temporary, &Arg0) == Error) 
  686.           RunErr(0, NULL);
  687.       }
  688. #else                    /* POWBUG */
  689.       if (makereal(pow(r1, r2), &Arg0) == Error) 
  690.          RunErr(0, NULL);
  691. #endif                    /* POWBUG */
  692.  
  693.       }
  694.  
  695. #ifdef LargeInts
  696.    else {
  697.       /*
  698.        * Neither Arg1 or Arg2 are real and at least one is a large int.
  699.        */
  700.       if (bigpow(&Arg1, &Arg2, &Arg0) == Error)  /* alcbignum failed */
  701.      RunErr(0, NULL);
  702.       }
  703. #endif                    /* LargeInts */
  704.  
  705.    Return;
  706.    }
  707.  
  708. #if AMIGA
  709. #if AZTEC_C
  710. #ifdef AZTECHACK
  711. #undef RTACIS
  712. #endif                    /* AZTECHACK */
  713. #endif                    /* AZTEC_C */
  714. #endif                    /* AMIGA */
  715.  
  716. #ifndef LargeInts
  717. long ipow(n1, n2)
  718. long n1, n2;
  719.    {
  720.    long result;
  721.  
  722.    if (n1 == 0 && n2 <= 0) {
  723.       over_flow = 1;
  724.       return 0;
  725.       }
  726.    if (n2 < 0)
  727.       return 0;
  728.    result = 1L;
  729.    while (n2 > 0) {
  730.       if (n2 & 01L)
  731.          result *= n1;
  732.       n1 *= n1;
  733.       n2 >>= 1;
  734.       }
  735.    over_flow = 0;
  736.    return result;
  737.    }
  738. #endif                    /* LargeInts */
  739.