Example #1
0
/*
 *  compute X = (a * X + c) MOD m       where c = a
 */
void	m_apm_get_random(M_APM mrnd)
{

	if (M_firsttime2)         /* use the system time as the initial seed value */
	{
		M_firsttime2 = FALSE;

		M_rnd_aa = m_apm_init();
		M_rnd_XX = m_apm_init();
		M_rnd_mm = m_apm_init();
		M_rtmp0  = m_apm_init();
		M_rtmp1  = m_apm_init();

		/* set the multiplier M_rnd_aa and M_rnd_mm */

		m_apm_set_string(M_rnd_aa, "716805947629621");
		m_apm_set_string(M_rnd_mm, "1.0E15");

		M_get_rnd_seed(M_rnd_XX);
	}

	m_apm_multiply(M_rtmp0, M_rnd_XX, M_rnd_aa);
	m_apm_add(M_rtmp1, M_rtmp0, M_rnd_aa);
	m_apm_integer_div_rem(M_rtmp0, M_rnd_XX, M_rtmp1, M_rnd_mm);
	m_apm_copy(mrnd, M_rnd_XX);
	mrnd->m_apm_exponent -= 15;
}
Example #2
0
/*
 *      From Knuth, The Art of Computer Programming:
 *
 *      To compute GCD(u,v)
 *          
 *      A1:
 *	    if (v == 0)  return (u)
 *      A2:
 *          t = u mod v
 *	    u = v
 *	    v = t
 *	    goto A1
 */
void	m_apm_gcd_traditional(M_APM r, M_APM u, M_APM v)
{
M_APM   tmpD, tmpN, tmpU, tmpV;

tmpD = M_get_stack_var();
tmpN = M_get_stack_var();
tmpU = M_get_stack_var();
tmpV = M_get_stack_var();

m_apm_absolute_value(tmpU, u);
m_apm_absolute_value(tmpV, v);

while (TRUE)
  {
   if (tmpV->m_apm_sign == 0)
     break;

   m_apm_integer_div_rem(tmpD, tmpN, tmpU, tmpV);
   m_apm_copy(tmpU, tmpV);
   m_apm_copy(tmpV, tmpN);
  }

m_apm_copy(r, tmpU);
M_restore_stack(4);
}
Example #3
0
static int Bidiv(lua_State *L)			/** idiv(x,y) */
{
 M_APM a=Bget(L,1);
 M_APM b=Bget(L,2);
 M_APM q=Bnew(L);
 M_APM r=Bnew(L);
 m_apm_integer_div_rem(q,r,a,b);
 return 2;
}
Example #4
0
/*
 *      functions returns TRUE if the M_APM input number is prime
 *                        FALSE if it is not
 */
int     is_number_prime(M_APM input)
{
int     ii, ret, index;
char    sbuf[32];

/*
 *      for reference:
 *
 *      table size of 2 to filter multiples of 2 and 3 
 *      table size of 8 to filter multiples of 2, 3 and 5
 *      table size of 480 to filter multiples of 2,3,5,7, and 11
 *
 *      this increment table will filter out all numbers
 *      that are multiples of 2,3,5 and 7.
 */

static  char  incr_table[48] = {
        2, 4, 2, 4, 6, 2, 6, 4, 2, 4, 6, 6, 2, 6, 4, 2,
        6, 4, 6, 8, 4, 2, 4, 2, 4, 8, 6, 4, 6, 2, 4, 6,
        2, 6, 6, 4, 2, 4, 6, 2, 6, 4, 2, 4, 2, 10, 2, 10 };
   
/* 
 *  since the real algorithm starts at 11 (to syncronize
 *  with the increment table), we will cheat for numbers < 10.
 */

if (m_apm_compare(input, MM_Ten) <= 0)
  {
   m_apm_to_integer_string(sbuf, input);
   ii = atoi(sbuf);

   if (ii == 2 || ii == 3 || ii == 5 || ii == 7)
     return(TRUE);
   else
     return(FALSE);
  }

ret   = FALSE;
index = 0;

/*
 *    see if the input number is a
 *    multiple of 3, 5, or 7.
 */

m_apm_integer_div_rem(M_quot, M_rem, input, MM_Three);
if (m_apm_sign(M_rem) == 0)               /* remainder == 0 */
  return(ret);

m_apm_integer_div_rem(M_quot, M_rem, input, MM_Five);
if (m_apm_sign(M_rem) == 0)
  return(ret);

m_apm_set_long(M_digit, 7L);
m_apm_integer_div_rem(M_quot, M_rem, input, M_digit);
if (m_apm_sign(M_rem) == 0)
  return(ret);

ii = m_apm_exponent(input) + 16;

m_apm_sqrt(M_tmp1, ii, input);
m_apm_add(M_limit, MM_Two, M_tmp1);
   
m_apm_set_long(M_digit, 11L);              /* now start at '11' to check */
   
while (TRUE)
  {
   if (m_apm_compare(M_digit, M_limit) >= 0)
     {
      ret = TRUE;
      break;
     }
   
   m_apm_integer_div_rem(M_quot, M_rem, input, M_digit);
   
   if (m_apm_sign(M_rem) == 0)         /* remainder == 0 */
     break;
   
   m_apm_set_long(M_tmp1, (long)incr_table[index]);
   m_apm_add(M_tmp0, M_digit, M_tmp1);
   m_apm_copy(M_digit, M_tmp0);

   if (++index == 48)
     index = 0;
  }

return(ret);
}
Example #5
0
void	m_apm_integer_div_rem_mt(M_APM qq, M_APM rr, M_APM aa, M_APM bb)
{
	m_apm_enter();
	m_apm_integer_div_rem(qq,rr,aa,bb);
	m_apm_leave();
}