Example #1
0
void	M_4_byte_multiply(UCHAR *r, UCHAR *a, UCHAR *b)
{
int	b0, jj;
UCHAR   *cp1, *cp2, numdiv, numrem;

memset(r, 0, 8);               /* zero out 8 byte result */
jj = 3;

/* loop for one number [b], un-roll the inner 'loop' [a] */

while (1)
  {
   b0  = (int)b[jj];
   cp1 = r + (3 + jj);
   cp2 = cp1 + 1;

   M_get_div_rem((b0 * a[3]), &numdiv, &numrem);
   
   *cp2 += numrem;
   *cp1 += numdiv;
   
   if (*cp2 >= 100)
     {
      *cp2 -= 100;
      *cp1 += 1;
     }
   
   cp1--;
   cp2--;
   
   if (*cp2 >= 100)
     {
      *cp2 -= 100;
      *cp1 += 1;
     }
   
   M_get_div_rem((b0 * a[2]), &numdiv, &numrem);
   
   *cp2 += numrem;
   *cp1 += numdiv;
   
   if (*cp2 >= 100)
     {
      *cp2 -= 100;
      *cp1 += 1;
     }
   
   cp1--;
   cp2--;
   
   if (*cp2 >= 100)
     {
      *cp2 -= 100;
      *cp1 += 1;
     }
   
   M_get_div_rem((b0 * a[1]), &numdiv, &numrem);
   
   *cp2 += numrem;
   *cp1 += numdiv;
   
   if (*cp2 >= 100)
     {
      *cp2 -= 100;
      *cp1 += 1;
     }
   
   cp1--;
   cp2--;
   
   if (*cp2 >= 100)
     {
      *cp2 -= 100;
      *cp1 += 1;
     }
   
   M_get_div_rem((b0 * a[0]), &numdiv, &numrem);
   
   *cp2 += numrem;
   *cp1 += numdiv;
   
   if (*cp2 >= 100)
     {
      *cp2 -= 100;
      *cp1 += 1;
     }
   
   if (jj-- == 0)
     break;
  }
}
Example #2
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);
  }
}