Sindbad~EG File Manager

Current Path : /usr/home/beeson/Otter-Lambda/yyy/algebra/
Upload File :
Current File : /usr/home/beeson/Otter-Lambda/yyy/algebra/numpower.c

/* M. Beeson, three numerical operators for MathXpert,
Original date: 2.15.97
Last modified 3.12.99
*/

#define ALGEBRA_DLL
#include <string.h>
#include <assert.h>
#include "globals.h"
#include "ops.h"
#include "nfactor.h"
#include "deval.h"
#include "order.h"  /* numerical */

/*__________________________________________________________________*/
static int express_as_power(term t, term n, term *ans)
/* t should be a number, that is, a positive or negative integer
or rational.  n should be a positive integer (not a bignum).
Express t in the form *ans^n if possible, returning 0.
Return 1 for failure, in which case *ans is garbage.
*/
{ aflag arithflag,saveit;
  int err;
  if(!ISINTEGER(n))
     return 1;
  saveit = arithflag = get_arithflag();
  arithflag.ratexp = arithflag.roots = 1;
  err =  arith(make_power(t,reciprocal(n)),ans,arithflag);
  set_arithflag(saveit);
  return err ? 1 : 0;
}

/*___________________________________________________________________*/
MEXPORT_ALGEBRA int writenumberassquare(term t, term arg, term *next, char *reason)
/* express a number as a square */
{ term base;
  int err = express_as_power(t,two,&base);
  if(err)
     return 1;
  *next = make_power(base,two);
  HIGHLIGHT(*next);
  PROTECT(*next);
  strcpy(reason, english(1850));  /* write as square */
  return 0;
}
/*___________________________________________________________________*/
MEXPORT_ALGEBRA int writenumberascube(term t, term arg, term *next, char *reason)
/* express a number as a cube */
{ term base;
  int err = express_as_power(t,three,&base);
  if(err)
     return 1;
  *next = make_power(base,three);
  HIGHLIGHT(*next);
  PROTECT(*next);    /* so arithmetic doesn't just undo this again */
    /* This is needed to make ShowStep duplicate 
       AutoStep on 8-27x^3.  Differenceofcubes imitates
       writenumberascube but does PROTECT the result.
       If writenumberascube doesn't also PROTECT its result,
       then the ShowStep solution isn't the same as AutoStep's 
    */
  strcpy(reason,english(1851));  /* write as cube */
  return 0;
}
/*___________________________________________________________________*/
MEXPORT_ALGEBRA int writenumberaspower(term t, term arg, term *next, char *reason)
/* express a number as a user-specified power */
{ term base;
  int err;
  if(!INTEGERP(arg))
     return 0;   /* assert(0), check_input_arg prevents it */
  if(INTEGERP(arg) && TYPE(arg) == BIGNUM)
     return 1;
  err = express_as_power(t,arg,&base);
  if(err)
     return 1;
  *next = make_power(base,arg);
  HIGHLIGHT(*next);
  PROTECT(*next);  /* see explanation in writenumberascube */
  strcpy(reason,english(1852));  /* express in form a^? */
  return 0;
}
/*___________________________________________________________________*/
MEXPORT_ALGEBRA int writenumberaspowerof(term t, term arg, term *next, char *reason)
/* express a number as an integer power of a user-specified base */
/* express in form ?^n */
{ term power;
  double z;
  long kk;
  if(!numerical(arg) || !numerical(t))
     return 1;
  deval(make_fraction(ln1(t),ln1(arg)),&z);
  if(z == BADVAL)
     return 1;
  if(!nearint(z,&kk))
     return 1;  /* new power would not be an integer */
  power = make_int(kk);
  *next = make_power(arg,power);
  HIGHLIGHT(*next);
  PROTECT(*next);
  strcpy(reason,english(2359));  /* express as power of ? */
  return 0;
}

/*______________________________________________________________________*/
MEXPORT_ALGEBRA int possible_power(term t)
/* return 1 if the Term Selection Menu should show writenumberaspower */
{ unsigned short i;
  unsigned nfactors;
  term u,v;
  if(!NUMBER(t))
     return 0;
  if(ZERO(t)|| ONE(t))
     return 0;
  if(INTEGERP(t) && TYPE(t) == BIGNUM)
     return 1;
  if(OBJECT(t) && TYPE(t) == DOUBLE)
     return 0;
  if(ISINTEGER(t))
     { long m = INTDATA(t);
       if(m == 2 || m == 3 || m == 5 || m == 7)
          return 0;  /* avoid calling factor_integer */
       if(m == 4 || m == 6 || m == 8)
          return 1;
       factor_integer(t,&nfactors,&u);
       /* all powers in the factorization must be at least 4 */
       for(i=0;i<nfactors;i++)
          { v = ARG(i,u);
            if(FUNCTOR(v) != '^' || !ISINTEGER(ARG(1,v)) || INTDATA(ARG(1,v)) < 4)
                return 0;
          }
       return 1;
     }
  if(FRACTION(t))
     return possible_power(ARG(0,t)) && possible_power(ARG(1,t));
  return 0;
}


Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists