예제 #1
0
void reset_registers(void)
{
  int i;

  for(i = 0; i < NUM_REGS; ++i) {
    mp_int_zero(g_zreg + i);
    mp_rat_zero(g_qreg + i);
  }
}
예제 #2
0
파일: pi.c 프로젝트: creachadair/imath
/*
  Compute mul * atan(1/x) to prec digits of precision, and store the
  result in sum.

  Computes atan(1/x) using the formula:

               1     1      1      1
  atan(1/x) = --- - ---- + ---- - ---- + ...
               x    3x^3   5x^5   7x^7

 */
mp_result arctan(mp_small radix, mp_small mul, mp_small x, mp_small prec,
                 mp_int sum) {
  mpz_t t, v;
  mp_result res;
  mp_small rem, sign = 1, coeff = 1;

  mp_int_init(&t);
  mp_int_init(&v);
  ++prec;

  /* Compute mul * radix^prec * x
     The initial multiplication by x saves a special case in the loop for
     the first term of the series.
   */
  if ((res = mp_int_expt_value(radix, prec, &t)) != MP_OK ||
      (res = mp_int_mul_value(&t, mul, &t)) != MP_OK ||
      (res = mp_int_mul_value(&t, x, &t)) != MP_OK)
    goto CLEANUP;

  x *= x; /* assumes x <= sqrt(MP_SMALL_MAX) */
  mp_int_zero(sum);

  do {
    if ((res = mp_int_div_value(&t, x, &t, &rem)) != MP_OK) goto CLEANUP;

    if ((res = mp_int_div_value(&t, coeff, &v, &rem)) != MP_OK) goto CLEANUP;

    /* Add or subtract the result depending on the current sign (1 = add) */
    if (sign > 0)
      res = mp_int_add(sum, &v, sum);
    else
      res = mp_int_sub(sum, &v, sum);

    if (res != MP_OK) goto CLEANUP;
    sign = -sign;
    coeff += 2;

  } while (mp_int_compare_zero(&t) != 0);

  res = mp_int_div_value(sum, radix, sum, NULL);

CLEANUP:
  mp_int_clear(&v);
  mp_int_clear(&t);

  return res;
}
예제 #3
0
static int       parse_int_values(testspec_t *t, mp_int *in, mp_int *out,
				  mp_result *rval)
{
  int i, pos = 0;
  char *str;

  if(rval != NULL)
    *rval = MP_OK;  /* default */

  if(in != NULL) {
    for(i = 0; i < t->num_inputs; ++i) {
      str = t->input[i];

      trim_line(str);

      if(*str == '=') {
	int k = abs(atoi(str + 1)) - 1;
	
	if(k < 0 || k >= i) {
	  fprintf(stderr, "Line %d: Invalid input back-reference [%s]\n",
		  t->line, str);
	  return 0;
	}
      
	in[i] = in[k];
      } else {
	mp_int reg = g_zreg + pos++; /* grab next free register */
	
	if(read_int_value(reg, str) != MP_OK) {
	  fprintf(stderr, "Line %d: Invalid input value [%s]\n",
		  t->line, str);
	  return 0;
	}
	
	in[i] = reg;
      }
    }
  }

  for(i = 0; i < t->num_outputs; ++i) {
    mp_int reg = g_zreg + pos++;

    str = t->output[i];
    
    trim_line(str);

    if(strcmp(str, "?") == 0)
      mp_int_zero(reg);
    else if(*str == '$') {
      mp_result code;

      if(!parse_result_code(str, &code)) {
	fprintf(stderr, "Line %d: Invalid result code [%s]\n", 
		t->line, str);
	return 0;
      }
      else if(rval == NULL) {
	fprintf(stderr, "Line %d: Result code not permitted here [%s]\n",
		t->line, str);
	return 0;
      }
      else
	*rval = code;

      /* Provide a dummy value for the corresponding output */
      mp_int_zero(reg);
    }
    else if(out != NULL && read_int_value(reg, str) != MP_OK) {
      fprintf(stderr, "Line %d: Invalid output value [%s]\n",
	      t->line, str);
      return 0;
    }

    if(out != NULL)
      out[i] = reg;
  }

  return 1;
}