/* Copyright (C) 1996 by Thomas Glen Smith. All Rights Reserved. */
/* cplxin APL2 V1.0.0 ***************************************************
* Called by vector. *
* Identical to dublin in function and argument list, except the second *
* argument (b) must be a pointer to an array of two doubles. If the *
* derived numeric constant is a complex number, *(b+1) will be non-zero.*
************************************************************************/
#define INCLUDES APLCHDEF+MATH+STRING
#include "includes.h"
int cplxin(a,b,c,d,e)
char *a,*e; /* Start and end of string containing numeric constant. */
double *b;
int *c,*d;
{
Cos; Dublin; Fmod; Pitimes; Sin;
extern char *aplchar[]; /* global APL character array */
int len1, len2=0, td;
char type;
double angle, magnitud, sign;
*b = *(b + 1) = 0e0;
len1 = dublin(a, b, c, d, e);
for (;;) { /* lets me use break */
if (len1 == 0) break;
if (*(a + len1) == *(aplchar[APL_J])) type = 'j';
else if (*(a + len1) == *(aplchar[APL_D])) type = 'd';
else if (*(a + len1) == *(aplchar[APL_R])) type = 'r';
else break; /* not complex */
len1++; /* add 1 for length of "j" */
switch (*(a + len1)) {
case ' ': case '\n': case '\t':
break; /* no white space allowed after "j". */
default:
if (*d == 0) { /* integer found for real part */
*d = 1; /* indicate real found */
*b = *c; /* convert integer to real */
}
len2 = dublin(a + len1, b + 1, c, &td, e);
if (len2 == 0) break;
if (td == 0) *(b + 1) = *c; /* convert to double */
if (type != 'j') { /* translate polar coord. */
magnitud = *b;
angle = *(b + 1);
if (type == 'd') { /* translate degrees */
sign = (angle < 0) ? -1.0 : 1.0;
if (sign == -1.0) angle = -angle;
angle = fmod(angle, 360.0);
if (sign == -1.0) angle = 360.0 - angle;
angle = angle / 180.0 * pitimes(1.0);
}
*b = magnitud * cos(angle);
*(b + 1) = magnitud * sin(angle);
}
break;
} /* end switch */
if (len2 == 0) len1--; /* back off j, d, r */
break; /* final break of for(;;) */
}
return(len1 + len2);
}