Пример #1
0
M_APM	m_apm_init()
{
static	int firsttime = TRUE;
M_APM	atmp;

if (firsttime)
  {
   firsttime = FALSE;
   M_init_util_data();
   M_init_trig_globals();
  }

if ((atmp = MAPM_MALLOC(sizeof(struct M_APM_struct))) == NULL)
  {
   fprintf(stderr,"\'m_apm_init\', Out of memory\n");
   exit(4);
  }

atmp->m_apm_id           = M_APM_IDENT;
atmp->m_apm_malloclength = 80;
atmp->m_apm_datalength   = 1;
atmp->m_apm_exponent     = 0;
atmp->m_apm_sign         = 0;

if ((atmp->m_apm_data = (UCHAR *)MAPM_MALLOC(84)) == NULL)
  {
   fprintf(stderr,"\'m_apm_init\', Out of memory\n");
   exit(6);
  }

atmp->m_apm_data[0] = 0;
return(atmp);
}
Пример #2
0
/*
	compute  int *n  = round_to_nearest_int(a / log(2))
	         M_APM b = MAPM version of *n

        returns      0: OK
		 -1, 1: failure
*/
int	M_exp_compute_nn(int *n, M_APM b, M_APM a)
{
M_APM	tmp0, tmp1;
void	*vp;
char    *cp, sbuf[48];
int	kk;

*n   = 0;
vp   = NULL;
cp   = sbuf;
tmp0 = M_get_stack_var();
tmp1 = M_get_stack_var();

/* find 'n' and convert it to a normal C int            */
/* we just need an approx 1/log(2) for this calculation */

m_apm_multiply(tmp1, a, MM_exp_log2R);

/* round to the nearest int */

if (tmp1->m_apm_sign >= 0)
  {
   m_apm_add(tmp0, tmp1, MM_0_5);
   m_apm_floor(tmp1, tmp0);
  }
else
  {
   m_apm_subtract(tmp0, tmp1, MM_0_5);
   m_apm_ceil(tmp1, tmp0);
  }

kk = tmp1->m_apm_exponent;
if (kk >= 42)
  {
   if ((vp = (void *)MAPM_MALLOC((kk + 16) * sizeof(char))) == NULL)
     {
      /* fatal, this does not return */

      M_apm_log_error_msg(M_APM_FATAL, "\'M_exp_compute_nn\', Out of memory");
     }

   cp = (char *)vp;
  }

m_apm_to_integer_string(cp, tmp1);
*n = atoi(cp);

m_apm_set_long(b, (long)(*n));

kk = m_apm_compare(b, tmp1);

if (vp != NULL)
  MAPM_FREE(vp);

M_restore_stack(2);
return(kk);
}
Пример #3
0
void	m_apm_to_integer_string(char *s, M_APM mtmp)
{
	void    *vp;
	UCHAR	*ucp, numdiv, numrem;
	char	*cp, *p, sbuf[128];
	int	ct, dl, numb, ii;

	vp = NULL;
	ct = mtmp->m_apm_exponent;
	dl = mtmp->m_apm_datalength;

	/*
	 *  if |input| < 1, result is "0"
	 */

	if (ct <= 0 || mtmp->m_apm_sign == 0)
	{
		s[0] = '0';
		s[1] = '\0';
		return;
	}

	if (ct > 112)
	{
		if ((vp = (void *)MAPM_MALLOC((ct + 32) * sizeof(char))) == NULL)
		{
			/* fatal, this does not return */

			M_apm_log_error_msg(M_APM_FATAL,
			                    "\'m_apm_to_integer_string\', Out of memory");
		}

		cp = (char *)vp;
	}
	else
	{
		cp = sbuf;
	}

	p  = cp;
	ii = 0;

	/* handle a negative number */

	if (mtmp->m_apm_sign == -1)
	{
		ii = 1;
		*p++ = '-';
	}

	/* get num-bytes of data (#digits / 2) to use in the string */

	if (ct > dl)
		numb = (dl + 1) >> 1;
	else
Пример #4
0
int	M_get_stack_ptr(int sz)
{
int	i, k;
UCHAR   *cp;

k = ++M_mul_stack_ptr;

/* if size is 0, just need to malloc and return */
if (mul_stack_data_size[k] == 0)
  {
   if ((i = sz) < 16)
     i = 16;

   if ((cp = (UCHAR *)MAPM_MALLOC(i + 4)) == NULL)
     {
      /* fatal, this does not return */

      M_apm_log_error_msg(M_APM_FATAL, M_stack_ptr_error_msg);
     }

   mul_stack_data[k]      = cp;
   mul_stack_data_size[k] = i;
  }
else        /* it has been malloc'ed, see if it's big enough */
  {
   if (sz > mul_stack_data_size[k])
     {
      cp = mul_stack_data[k];

      if ((cp = (UCHAR *)MAPM_REALLOC(cp, (sz + 4))) == NULL)
        {
         /* fatal, this does not return */
   
         M_apm_log_error_msg(M_APM_FATAL, M_stack_ptr_error_msg);
        }
   
      mul_stack_data[k]      = cp;
      mul_stack_data_size[k] = sz;
     }
  }

return(k);
}
Пример #5
0
char	*m_apm_to_fixpt_stringexp(int dplaces, M_APM atmp, 
				  char ch_radx, char ch_sep, int ct_sep)
{
int	places, xp, dl, ii;
char	*cpr;

places = dplaces;

dl = atmp->m_apm_datalength;
xp = atmp->m_apm_exponent;

if (places < 0)				/* show ALL digits */
  {
   if (xp < 0)
      ii = dl - xp;
   else
     {
      if (dl > xp)
        ii = dl;
      else
        ii = xp;
     }
  }
else
  {
   ii = places;
      
   if (xp > 0)
     ii += xp;
  }

if (ct_sep != 0 && ch_sep != 0 && xp > 0)
  ii += xp / ct_sep;

if ((cpr = (char *)MAPM_MALLOC((ii + 32) * sizeof(char))) == NULL)
  return(NULL);

m_apm_to_fixpt_stringex(cpr,places,atmp,ch_radx,ch_sep,ct_sep);

return(cpr);
}
Пример #6
0
void	M_fast_mul_fft(UCHAR *ww, UCHAR *uu, UCHAR *vv, int nbytes)
{
int             mflag, i, j, nn2, nn;
double          carry, nnr, dtemp, *a, *b;
UCHAR           *w0;
unsigned long   ul;

if (M_size < 0)                  /* if first time in, setup working arrays */
  {
   if (M_get_sizeof_int() == 2)  /* if still using 16 bit compilers */
     M_size = 1030;
   else
     M_size = 8200;

   M_aa_array = (double *)MAPM_MALLOC(M_size * sizeof(double));
   M_bb_array = (double *)MAPM_MALLOC(M_size * sizeof(double));
   
   if ((M_aa_array == NULL) || (M_bb_array == NULL))
     {
      /* fatal, this does not return */

      M_apm_log_error_msg(M_APM_EXIT, "\'M_fast_mul_fft\', Out of memory");
     }
  }

nn  = nbytes;
nn2 = nbytes >> 1;

if (nn > M_size)
  {
   mflag = TRUE;

   a = (double *)MAPM_MALLOC((nn + 8) * sizeof(double));
   b = (double *)MAPM_MALLOC((nn + 8) * sizeof(double));
   
   if ((a == NULL) || (b == NULL))
     {
      /* fatal, this does not return */

      M_apm_log_error_msg(M_APM_EXIT, "\'M_fast_mul_fft\', Out of memory");
     }
  }
else
  {
   mflag = FALSE;

   a = M_aa_array;
   b = M_bb_array;
  }

/*
 *   convert normal base 100 MAPM numbers to base 10000
 *   for the FFT operation.
 */

i = 0;
for (j=0; j < nn2; j++)
  {
   a[j] = (double)((int)uu[i] * 100 + uu[i+1]);
   b[j] = (double)((int)vv[i] * 100 + vv[i+1]);
   i += 2;
  }

/* zero fill the second half of the arrays */

for (j=nn2; j < nn; j++)
  {
   a[j] = 0.0;
   b[j] = 0.0;
  }

/* perform the forward Fourier transforms for both numbers */

M_rdft(nn, 1, a);
M_rdft(nn, 1, b);

/* perform the convolution ... */

b[0] *= a[0];
b[1] *= a[1];

for (j=3; j <= nn; j += 2)
  {
   dtemp  = b[j-1];
   b[j-1] = dtemp * a[j-1] - b[j] * a[j];
   b[j]   = dtemp * a[j] + b[j] * a[j-1];
  }

/* perform the inverse transform on the result */

M_rdft(nn, -1, b);

/* perform a final pass to release all the carries */
/* we are still in base 10000 at this point        */

carry = 0.0;
j     = nn;
nnr   = 2.0 / (double)nn;

while (1)
  {
   dtemp = b[--j] * nnr + carry + 0.5;
   ul    = (unsigned long)(dtemp * 1.0E-4);
   carry = (double)ul;
   b[j]  = dtemp - carry * 10000.0;

   if (j == 0)
     break;
  }

/* copy result to our destination after converting back to base 100 */

w0 = ww;
M_get_div_rem((int)ul, w0, (w0 + 1));

for (j=0; j <= (nn - 2); j++)
  {
   w0 += 2;
   M_get_div_rem((int)b[j], w0, (w0 + 1));
  }

if (mflag)
  {
   MAPM_FREE(b);
   MAPM_FREE(a);
  }
}
Пример #7
0
void	m_apm_to_fixpt_string(char *ss, int dplaces, M_APM mtmp)
{
M_APM   ctmp;
void	*vp;
int	places, i2, ii, jj, kk, xp, dl, numb;
UCHAR   *ucp, numdiv, numrem;
char	*cpw, *cpd, sbuf[128];

ctmp   = M_get_stack_var();
vp     = NULL;
cpd    = ss;
places = dplaces;

/* just want integer portion if places == 0 */

if (places == 0)
  {
   if (mtmp->m_apm_sign >= 0)
     m_apm_add(ctmp, mtmp, MM_0_5);
   else
     m_apm_subtract(ctmp, mtmp, MM_0_5);

   m_apm_to_integer_string(cpd, ctmp);

   M_restore_stack(1);
   return;
  }

if (places > 0)
  M_apm_round_fixpt(ctmp, places, mtmp);
else
  m_apm_copy(ctmp, mtmp);	  /* show ALL digits */

if (ctmp->m_apm_sign == 0)        /* result is 0 */
  {
   if (places < 0)
     {
      cpd[0] = '0';		  /* "0.0" */
      cpd[1] = '.';
      cpd[2] = '0';
      cpd[3] = '\0';
     }
   else
     {
      memset(cpd, '0', (places + 2));	/* pre-load string with all '0' */
      cpd[1] = '.';
      cpd[places + 2] = '\0';
     }

   M_restore_stack(1);
   return;
  }

xp   = ctmp->m_apm_exponent;
dl   = ctmp->m_apm_datalength;
numb = (dl + 1) >> 1;

if (places < 0)
  {
   if (dl > xp)
     jj = dl + 16;
   else
     jj = xp + 16;
  }
else
  {
   jj = places + 16;
   
   if (xp > 0)
     jj += xp;
  }

if (jj > 112)
  {
   if ((vp = (void *)MAPM_MALLOC((jj + 16) * sizeof(char))) == NULL)
     {
      /* fatal, this does not return */

      M_apm_log_error_msg(M_APM_FATAL, 
                          "\'m_apm_to_fixpt_string\', Out of memory");
     }

   cpw = (char *)vp;
  }
else
  {
   cpw = sbuf;
  }

/*
 *  at this point, the number is non-zero and the the output
 *  string will contain at least 1 significant digit.
 */

if (ctmp->m_apm_sign == -1) 	  /* negative number */
  {
   *cpd++ = '-';
  }

ucp = ctmp->m_apm_data;
ii  = 0;

/* convert MAPM num to ASCII digits and store in working char array */

while (TRUE)
  {
   M_get_div_rem_10((int)(*ucp++), &numdiv, &numrem);

   cpw[ii++] = numdiv + '0';
   cpw[ii++] = numrem + '0';

   if (--numb == 0)
     break;
  }

i2 = ii;		/* save for later */

if (places < 0)		/* show ALL digits */
  {
   places = dl - xp;

   if (places < 1)
     places = 1;
  }

/* pad with trailing zeros if needed */

kk = xp + places + 2 - ii;

if (kk > 0)
  memset(&cpw[ii], '0', kk);

if (xp > 0)          /* |num| >= 1, NO lead-in "0.nnn" */
  {
   ii = xp + places + 1;
   jj = 0;

   for (kk=0; kk < ii; kk++)
     {
      if (kk == xp)
        cpd[jj++] = '.';

      cpd[jj++] = cpw[kk];
     }

   cpd[ii] = '\0';
  }
else			/* |num| < 1, have lead-in "0.nnn" */
  {
   jj = 2 - xp;
   ii = 2 + places;
   memset(cpd, '0', (ii + 1));	/* pre-load string with all '0' */
   cpd[1] = '.';		/* assign decimal point */

   for (kk=0; kk < i2; kk++)
     {
      cpd[jj++] = cpw[kk];
     }

   cpd[ii] = '\0';
  }

if (vp != NULL)
  MAPM_FREE(vp);

M_restore_stack(1);
}
Пример #8
0
void	m_apm_to_fixpt_stringex(char *s, int dplaces, M_APM atmp, 
				char ch_radix, char ch_sep, int count_sep)
{
M_APM   btmp;
char    ch, *cpd, *cps;
int	ii, jj, kk, ct, dl, xp, no_sep_flg, places;

btmp       = M_get_stack_var();
places     = dplaces;
cpd        = s;
no_sep_flg = FALSE;

m_apm_absolute_value(btmp, atmp);	/* do conversion of positive number */

if (ch_sep == 0 || count_sep == 0)	/* no separator char OR count */
  no_sep_flg = TRUE;

/* determine how much memory to get for the temp string */

dl = btmp->m_apm_datalength;
xp = btmp->m_apm_exponent;

if (places < 0)				/* show ALL digits */
  {
   if (xp < 0)
      ii = dl - xp;
   else
     {
      if (dl > xp)
        ii = dl;
      else
        ii = xp;
     }
  }
else
  {
   ii = places;
      
   if (xp > 0)
     ii += xp;
  }

if ((cps = (char *)MAPM_MALLOC((ii + 32) * sizeof(char))) == NULL)
  {
   /* fatal, this does not return */

   M_apm_log_error_msg(M_APM_FATAL, 
                       "\'m_apm_to_fixpt_stringex\', Out of memory");
  }

m_apm_to_fixpt_string(cps, places, btmp);

/*
 *  the converted string may be all 'zero', 0.0000...
 *  if so and the original number is negative,
 *  do NOT set the '-' sign of our output string.
 */

if (atmp->m_apm_sign == -1)		/* if input number negative */
  {
   kk = 0;
   jj = 0;

   while (TRUE)
     {
      ch = cps[kk++];
      if ((ch == '\0') || (jj != 0))
        break;

      if (isdigit((int)ch))
        {
	 if (ch != '0')
	   jj = 1;
	}
     }

   if (jj)
     *cpd++ = '-';
  }

ct = M_strposition(cps, ".");      /* find the default (.) radix char */

if (ct == -1)			   /* if not found .. */
  {
   strcat(cps, ".");               /* add one */
   ct = M_strposition(cps, ".");   /* and then find it */
  }

if (places == 0)		   /* int format, terminate at radix char */
  cps[ct] = '\0';
else
  cps[ct] = ch_radix;		   /* assign the radix char */

/*
 *  if the number is small enough to not have any separator char's ...
 */

if (ct <= count_sep)
  no_sep_flg = TRUE;

if (no_sep_flg)
  {
   strcpy(cpd, cps);

  }
else
  {
   jj = 0;
   kk = count_sep;
   ii = ct / count_sep;

   if ((ii = ct - ii * count_sep) == 0)
     ii = count_sep;

   while (TRUE)				/* write out the first 1,2  */
     {					/* (up to count_sep) digits */
      *cpd++ = cps[jj++];

      if (--ii == 0)
        break;
     }

   while (TRUE)				/* write rest of the string   */
     {
      if (kk == count_sep)		/* write a new separator char */
        {
	 if (jj != ct)			/* unless we're at the radix  */
	   {
            *cpd++ = ch_sep;		/* note that this also disables */
	    kk = 0;			/* the separator char AFTER     */
	   }				/* the radix char               */
	}

      if ((*cpd++ = cps[jj++]) == '\0')
        break;

      kk++;
     }
  }

MAPM_FREE(cps);
M_restore_stack(1);
}