Metropoli BBS
VIEWER: powerx.c MODE: TEXT (ASCII)
/* Copyright (C) 1992 by Thomas Glen Smith.  All Rights Reserved. */
/* powerx APL2 V1.0.0  *************************************************
* Power for complex numbers.                                           *
***********************************************************************/
#define INCLUDES MATH+TRIGKEYS
#include "includes.h"
#define ABS(v) ((v) > 0e0 ? (v) : -(v))
void powerx(left,rite,ret)
double *left,*rite,*ret;
{
	Circular; Circulax; Dabsx; Dividex; Mod;
	Power; Powerx; Timesx;
     extern int aplerr;
	extern double fuzz;
	double absval,n,neg,wrka[2],wrkb[2],wrkc[2];
     int i;

	
	if (ABS(*(rite+1)) > fuzz) { /* rite complex? */
     	*wrka = *rite;
          *(wrka+1) = 0e0;
          powerx(left,wrka,wrkb); /* wrkb = left * a */
          *wrka = circular(COS,*(left+1));
          *(wrka+1) = circular(SIN,*(left+1)); /*wrka=cos(b)+iXsin(b)*/
          timesx(wrkb,wrka,ret);
          return;
     }
	/* control reaches here only if rite is a real number */
	if (*(left+1) <= fuzz && *(left+1) >= fuzz) { /* left real? */
     	*(ret+1) = 0e0;
          *ret = power(*left,*rite);
          return;
     }
     else { /* left is complex */
	     neg = (*rite < 0e0) ? -1.0 : 1.0;
          absval = neg * *rite;
		if (mod(absval, 1.0) > fuzz) { /* Is it non-integer power? */
			/* a*1%n = magnitude:(|a}*1%n, angle:alpha%n */
			n = 1.0 / absval;
			if (mod(n, 1.0) > fuzz) { /* non-integer n in 1%n? */
				aplerr = 996; /* non-integer powers of complex numbers */
		          return;
			}
			dabsx(left,wrka); /* Get magnitude: |a. */
			*wrkb = power(*wrka,absval); /* Get (|a)*1%n. */
			*(wrkb+1) = atan2(*(left+1),*left) / n;
			*wrka = *wrkb * cos(*(wrkb+1));
			*(wrka + 1) = *wrkb * sin(*(wrkb+1));
	     } else {
			/* right is approximate integer */
	          i = absval; /* absolute integer value of rite */
	          XFR(wrka,left) /* copy left to wrka */
	          while(--i) {
	          	timesx(wrka,left,wrkb);
	          	XFR(wrka,wrkb) /* copy wrkb to wrka */
	          }
		}
          if (neg == -1.0) {
          	*wrkb = 1.0;
               *(wrkb+1) = 0.0;
          	dividex(wrkb,wrka,ret);
		}
          else XFR(ret,wrka);
     }
}
[ RETURN TO DIRECTORY ]