Example #1
0
File: gc.c Project: carthy/beard
void
test_gc_get_rational (void* data)
{
	mpq_t* num  = GC_NEW_RATIONAL(runtime);
	mpq_t* num2 = GC_NEW_RATIONAL(runtime);

	mpq_set_ui(*num, 2, 3);
	mpq_set_ui(*num2, 2, 3);
	mpq_add(*num, *num, *num2);

	tt_assert(mpq_cmp_ui(*num, 4, 3) == 0);

end:;
}
Example #2
0
APLRAT PrimFnMonQuoteDotRisR
    (APLRAT     aplRatRht,
     LPPRIMSPEC lpPrimSpec)

{
    APLRAT mpqRes = {0};
    UINT   uRht;

    // Check for indeterminates:  !N for integer N < 0
    if (mpq_integer_p (&aplRatRht)
     && mpq_cmp_ui (&aplRatRht, 0, 1) < 0)
        return *mpq_QuadICValue (&aplRatRht,        // No left arg
                                  ICNDX_QDOTn,
                                 &aplRatRht,
                                 &mpqRes,
                                  FALSE);
    // Check for PosInfinity
    if (IsMpqPosInfinity (&aplRatRht))
        return mpqPosInfinity;

    // If the denominator is 1,
    //   and the numerator fts in a UINT, ...
    if (mpq_integer_p (&aplRatRht)
     && mpz_fits_slong_p (mpq_numref (&aplRatRht)) NE 0)
    {
        // Initialize the result to 0/1
        mpq_init (&mpqRes);

        // Extract the numerator
        uRht = (UINT) mpz_get_si (mpq_numref (&aplRatRht));

        // Compute the factorial
        mpz_fac_ui (mpq_numref (&mpqRes), uRht);
    } else
        RaiseException (EXCEPTION_RESULT_VFP, 0, 0, NULL);

    return mpqRes;
} // End PrimFnMonQuoteDotRisR
void
check_n (void)
{
  int    ret;

  /* %n suppressed */
  {
    int n = 123;
    gmp_sscanf ("   ", " %*n", &n);
    ASSERT_ALWAYS (n == 123);
  }
  {
    int n = 123;
    fromstring_gmp_fscanf ("   ", " %*n", &n);
    ASSERT_ALWAYS (n == 123);
  }


#define CHECK_N(type, string)                           \
  do {                                                  \
    type  x[2];                                         \
    char  fmt[128];                                     \
    int   ret;                                          \
                                                        \
    x[0] = ~ (type) 0;                                  \
    x[1] = ~ (type) 0;                                  \
    sprintf (fmt, "abc%%%sn", string);                  \
    ret = gmp_sscanf ("abc", fmt, &x[0]);               \
                                                        \
    ASSERT_ALWAYS (ret == 0);                           \
                                                        \
    /* should write whole of x[0] and none of x[1] */   \
    ASSERT_ALWAYS (x[0] == 3);                          \
    ASSERT_ALWAYS (x[1] == (type) ~ (type) 0);		\
                                                        \
  } while (0)

  CHECK_N (char,      "hh");
  CHECK_N (long,      "l");
#if HAVE_LONG_LONG
  CHECK_N (long long, "L");
#endif
#if HAVE_INTMAX_T
  CHECK_N (intmax_t,  "j");
#endif
#if HAVE_PTRDIFF_T
  CHECK_N (ptrdiff_t, "t");
#endif
  CHECK_N (short,     "h");
  CHECK_N (size_t,    "z");

  /* %Zn */
  {
    mpz_t  x[2];
    mpz_init_set_si (x[0], -987L);
    mpz_init_set_si (x[1],  654L);
    ret = gmp_sscanf ("xyz   ", "xyz%Zn", x[0]);
    MPZ_CHECK_FORMAT (x[0]);
    MPZ_CHECK_FORMAT (x[1]);
    ASSERT_ALWAYS (ret == 0);
    ASSERT_ALWAYS (mpz_cmp_ui (x[0], 3L) == 0);
    ASSERT_ALWAYS (mpz_cmp_ui (x[1], 654L) == 0);
    mpz_clear (x[0]);
    mpz_clear (x[1]);
  }
  {
    mpz_t  x;
    mpz_init (x);
    ret = fromstring_gmp_fscanf ("xyz   ", "xyz%Zn", x);
    ASSERT_ALWAYS (ret == 0);
    ASSERT_ALWAYS (mpz_cmp_ui (x, 3L) == 0);
    mpz_clear (x);
  }

  /* %Qn */
  {
    mpq_t  x[2];
    mpq_init (x[0]);
    mpq_init (x[1]);
    mpq_set_ui (x[0], -987L, 654L);
    mpq_set_ui (x[1], 4115L, 226L);
    ret = gmp_sscanf ("xyz   ", "xyz%Qn", x[0]);
    MPQ_CHECK_FORMAT (x[0]);
    MPQ_CHECK_FORMAT (x[1]);
    ASSERT_ALWAYS (ret == 0);
    ASSERT_ALWAYS (mpq_cmp_ui (x[0], 3L, 1L) == 0);
    ASSERT_ALWAYS (mpq_cmp_ui (x[1], 4115L, 226L) == 0);
    mpq_clear (x[0]);
    mpq_clear (x[1]);
  }
  {
    mpq_t  x;
    mpq_init (x);
    ret = fromstring_gmp_fscanf ("xyz   ", "xyz%Qn", x);
    ASSERT_ALWAYS (ret == 0);
    ASSERT_ALWAYS (mpq_cmp_ui (x, 3L, 1L) == 0);
    mpq_clear (x);
  }

  /* %Fn */
  {
    mpf_t  x[2];
    mpf_init (x[0]);
    mpf_init (x[1]);
    mpf_set_ui (x[0], -987L);
    mpf_set_ui (x[1],  654L);
    ret = gmp_sscanf ("xyz   ", "xyz%Fn", x[0]);
    MPF_CHECK_FORMAT (x[0]);
    MPF_CHECK_FORMAT (x[1]);
    ASSERT_ALWAYS (ret == 0);
    ASSERT_ALWAYS (mpf_cmp_ui (x[0], 3L) == 0);
    ASSERT_ALWAYS (mpf_cmp_ui (x[1], 654L) == 0);
    mpf_clear (x[0]);
    mpf_clear (x[1]);
  }
  {
    mpf_t  x;
    mpf_init (x);
    ret = fromstring_gmp_fscanf ("xyz   ", "xyz%Fn", x);
    ASSERT_ALWAYS (ret == 0);
    ASSERT_ALWAYS (mpf_cmp_ui (x, 3L) == 0);
    mpf_clear (x);
  }
}
Example #4
0
static void
check_mixed (FILE *fout)
{
  int ch = 'a';
  signed char sch = -1;
  unsigned char uch = 1;
  short sh = -1;
  unsigned short ush = 1;
  int i = -1;
  int j = 1;
  unsigned int ui = 1;
  long lo = -1;
  unsigned long ulo = 1;
  float f = -1.25;
  double d = -1.25;
  long double ld = -1.25;

  ptrdiff_t p = 1;
  size_t sz = 1;

  mpz_t mpz;
  mpq_t mpq;
  mpf_t mpf;
  mp_rnd_t rnd = GMP_RNDN;

  mp_size_t limb_size = 3;
  mp_limb_t limb[3];

  mpfr_t mpfr;
  mpfr_prec_t prec = 53;

  mpz_init (mpz);
  mpz_set_ui (mpz, ulo);
  mpq_init (mpq);
  mpq_set_si (mpq, lo, ulo);
  mpf_init (mpf);
  mpf_set_q (mpf, mpq);

  mpfr_init2 (mpfr, prec);
  mpfr_set_f (mpfr, mpf, GMP_RNDN);

  limb[0] = limb[1] = limb[2] = ~ (mp_limb_t) 0;

  check_vfprintf (fout, "a. %Ra, b. %u, c. %lx%n", mpfr, ui, ulo, &j);
  check_length (1, j, 22, d);
  check_vfprintf (fout, "a. %c, b. %Rb, c. %u, d. %li%ln", i, mpfr, i,
                  lo, &ulo);
  check_length (2, ulo, 36, lu);
  check_vfprintf (fout, "a. %hi, b. %*f, c. %Re%hn", ush, 3, f, mpfr, &ush);
  check_length (3, ush, 29, hu);
  check_vfprintf (fout, "a. %hi, b. %f, c. %#.2Rf%n", sh, d, mpfr, &i);
  check_length (4, i, 29, d);
  check_vfprintf (fout, "a. %R*A, b. %Fe, c. %i%zn", rnd, mpfr, mpf, sz,
                  &sz);
  check_length (5, (unsigned long) sz, 34, lu); /* no format specifier "%zu" in C89 */
  check_vfprintf (fout, "a. %Pu, b. %c, c. %Zi%Zn", prec, ch, mpz, &mpz);
  check_length_with_cmp (6, mpz, 17, mpz_cmp_ui (mpz, 17), Zi);
  check_vfprintf (fout, "%% a. %#.0RNg, b. %Qx%Rn, c. %p", mpfr, mpq, &mpfr,
                  (void *) &i);
  check_length_with_cmp (7, mpfr, 15, mpfr_cmp_ui (mpfr, 15), Rg);

#ifndef NPRINTF_T
  check_vfprintf (fout, "%% a. %RNg, b. %Qx, c. %td%tn", mpfr, mpq, p, &p);
  check_length (8, (long) p, 20, ld); /* no format specifier "%td" in C89 */
#endif

#ifndef NPRINTF_L
  check_vfprintf (fout, "a. %RA, b. %Lf, c. %QX%zn", mpfr, ld, mpq, &sz);
  check_length (9, (unsigned long) sz, 30, lu); /* no format specifier "%zu" in C89 */
#endif

#ifndef NPRINTF_HH
  check_vfprintf (fout, "a. %hhi, b.%RA, c. %hhu%hhn", sch, mpfr, uch, &uch);
  check_length (10, (unsigned int) uch, 21, u); /* no format specifier "%hhu" in C89 */
#endif

#if (__GNU_MP_VERSION * 10 + __GNU_MP_VERSION_MINOR) >= 42
  /* The 'M' specifier was added in gmp 4.2.0 */
  check_vfprintf (fout, "a. %Mx b. %Re%Mn", limb[0], mpfr, &limb[0]);
  if (limb[0] != 14 + BITS_PER_MP_LIMB / 4 || limb[1] != ~ (mp_limb_t) 0
      || limb[2] != ~ (mp_limb_t) 0)
    {
      printf ("Error in test #11: mpfr_vfprintf did not print %d characters"
              " as expected\n", 14 + (int) BITS_PER_MP_LIMB / 4);
      exit (1);
    }

  limb[0] = ~ (mp_limb_t) 0;
  /* we tell vfprintf that limb array is 2 cells wide
     and check it doesn't go through */
  check_vfprintf (fout, "a. %Re .b %Nx%Nn", mpfr, limb, limb_size, limb,
                  limb_size - 1);
  if (limb[0] != 14 + 3 * BITS_PER_MP_LIMB / 4 || limb[1] != (mp_limb_t) 0
      || limb[2] != ~ (mp_limb_t) 0)
    {
      printf ("Error in test #12: mpfr_vfprintf did not print %d characters"
              " as expected\n", 14 + (int) BITS_PER_MP_LIMB / 4);
      exit (1);
    }
#endif

#if defined(HAVE_LONG_LONG) && !defined(NPRINTF_LL)
  {
    long long llo = -1;
    unsigned long long ullo = 1;

    check_vfprintf (fout, "a. %Re, b. %llx%Qn", mpfr, ullo, &mpq);
    check_length_with_cmp (21, mpq, 16, mpq_cmp_ui (mpq, 16, 1), Qu);
    check_vfprintf (fout, "a. %lli, b. %Rf%Fn", llo, mpfr, &mpf);
    check_length_with_cmp (22, mpf, 19, mpf_cmp_ui (mpf, 19), Fg);
  }
#endif

#if defined(_MPFR_H_HAVE_INTMAX_T) && !defined(NPRINTF_J)
  {
    intmax_t im = -1;
    uintmax_t uim = 1;

    check_vfprintf (fout, "a. %*RA, b. %ji%Qn", 10, mpfr, im, &mpq);
    check_length_with_cmp (31, mpq, 20, mpq_cmp_ui (mpq, 20, 1), Qu);
    check_vfprintf (fout, "a. %.*Re, b. %jx%Fn", 10, mpfr, uim, &mpf);
    check_length_with_cmp (32, mpf, 25, mpf_cmp_ui (mpf, 25), Fg);
  }
#endif

  mpfr_clear (mpfr);
  mpf_clear (mpf);
  mpq_clear (mpq);
  mpz_clear (mpz);
}
Example #5
0
static void
check_mixed (void)
{
  int ch = 'a';
#ifndef NPRINTF_HH
  signed char sch = -1;
  unsigned char uch = 1;
#endif
  short sh = -1;
  unsigned short ush = 1;
  int i = -1;
  int j = 1;
  unsigned int ui = 1;
  long lo = -1;
  unsigned long ulo = 1;
  float f = -1.25;
  double d = -1.25;
#if !defined(NPRINTF_T) || !defined(NPRINTF_L)
  long double ld = -1.25;
#endif

#ifndef NPRINTF_T
  ptrdiff_t p = 1, saved_p;
#endif
  size_t sz = 1;

  mpz_t mpz;
  mpq_t mpq;
  mpf_t mpf;
  mpfr_rnd_t rnd = MPFR_RNDN;

  mpfr_t mpfr;
  mpfr_prec_t prec;

  mpz_init (mpz);
  mpz_set_ui (mpz, ulo);
  mpq_init (mpq);
  mpq_set_si (mpq, lo, ulo);
  mpf_init (mpf);
  mpf_set_q (mpf, mpq);
  mpfr_init (mpfr);
  mpfr_set_f (mpfr, mpf, MPFR_RNDN);
  prec = mpfr_get_prec (mpfr);

  check_vprintf ("a. %Ra, b. %u, c. %lx%n", mpfr, ui, ulo, &j);
  check_length (1, j, 22, d);
  check_vprintf ("a. %c, b. %Rb, c. %u, d. %li%ln", i, mpfr, i, lo, &ulo);
  check_length (2, ulo, 36, lu);
  check_vprintf ("a. %hi, b. %*f, c. %Re%hn", ush, 3, f, mpfr, &ush);
  check_length (3, ush, 29, hu);
  check_vprintf ("a. %hi, b. %f, c. %#.2Rf%n", sh, d, mpfr, &i);
  check_length (4, i, 29, d);
  check_vprintf ("a. %R*A, b. %Fe, c. %i%zn", rnd, mpfr, mpf, sz, &sz);
  check_length (5, (unsigned long) sz, 34, lu); /* no format specifier '%zu' in C89 */
  check_vprintf ("a. %Pu, b. %c, c. %RUG, d. %Zi%Zn", prec, ch, mpfr, mpz, &mpz);
  check_length_with_cmp (6, mpz, 24, mpz_cmp_ui (mpz, 24), Zi);
  check_vprintf ("%% a. %#.0RNg, b. %Qx%Rn c. %p",
                 mpfr, mpq, &mpfr, (void *) &i);
  check_length_with_cmp (7, mpfr, 15, mpfr_cmp_ui (mpfr, 15), Rg);

#ifndef NPRINTF_T
  saved_p = p;
  check_vprintf ("%% a. %RNg, b. %Qx, c. %td%tn", mpfr, mpq, p, &p);
  if (p != 20)
    mpfr_fprintf (stderr, "Error in test 8, got '%% a. %RNg, b. %Qx, c. %td'\n", mpfr, mpq, saved_p);
  check_length (8, (long) p, 20, ld); /* no format specifier '%td' in C89 */
#endif

#ifndef NPRINTF_L
  check_vprintf ("a. %RA, b. %Lf, c. %QX%zn", mpfr, ld, mpq, &sz);
  check_length (9, (unsigned long) sz, 30, lu); /* no format specifier '%zu' in C89 */
#endif

#ifndef NPRINTF_HH
  check_vprintf ("a. %hhi, b. %Ra, c. %hhu%hhn", sch, mpfr, uch, &uch);
  check_length (10, (unsigned int) uch, 22, u); /* no format specifier '%hhu' in C89 */
#endif

#if defined(HAVE_LONG_LONG) && !defined(NPRINTF_LL)
  {
    long long llo = -1;
    unsigned long long ullo = 1;

    check_vprintf ("a. %Re, b. %llx%Qn", mpfr, ullo, &mpq);
    check_length_with_cmp (11, mpq, 16, mpq_cmp_ui (mpq, 16, 1), Qu);
    check_vprintf ("a. %lli, b. %Rf%lln", llo, mpfr, &ullo);
    check_length (12, ullo, 19, llu);
  }
#endif

#if defined(_MPFR_H_HAVE_INTMAX_T) && !defined(NPRINTF_J)
  {
    intmax_t im = -1;
    uintmax_t uim = 1;

    check_vprintf ("a. %*RA, b. %ji%Fn", 10, mpfr, im, &mpf);
    check_length_with_cmp (31, mpf, 20, mpf_cmp_ui (mpf, 20), Fg);
    check_vprintf ("a. %.*Re, b. %jx%jn", 10, mpfr, uim, &im);
    check_length (32, (long) im, 25, li); /* no format specifier "%ji" in C89 */
  }
#endif

  mpfr_clear (mpfr);
  mpf_clear (mpf);
  mpq_clear (mpq);
  mpz_clear (mpz);
}
Example #6
0
void setup_polynomial(polynomial *F, int numVars, FILE *IN, int polyNumber)
/***************************************************************\
* USAGE: setup the next polynomial described in IN              *
\***************************************************************/
{
  int i, j, rV, max, base = 10;

  // initialize the number of variables, degree & isReal
  F->numVariables = numVars;
  F->degree = 0;
  F->isReal = 1;

  // read in the number of terms
  fscanf(IN, "%d\n", &F->numTerms);

  // error checking - want number of terms >= 0
  if (F->numTerms <= 0)
  { // error
    printf("ERROR: The number of terms (%d) must be positive.\n", F->numTerms);
    // close file and exit
    fclose(IN);
    errExit(ERROR_INPUT_SYSTEM);
  }

  // allocate memory
  mpq_init(F->norm_sqr);
  F->coeff = (rational_complex_number *)errMalloc(F->numTerms * sizeof(rational_complex_number));
  F->exponents = (int **)errMalloc(F->numTerms * sizeof(int *));

  // setup the terms
  for (i = 0; i < F->numTerms; i++)
  { // allocate & initialize memory
    F->exponents[i] = (int *)errMalloc(numVars * sizeof(int));
    initialize_rational_number(F->coeff[i]);

    // read in exponents, compute degree, and perform error checking - want exponents >= 0
    max = 0;
    for (j = 0; j < numVars; j++)
    {
      fscanf(IN, "%d", &F->exponents[i][j]);
      if (F->exponents[i][j] < 0)
      { // error
        printf("ERROR: The exponent for variable %d in monomial %d of polynomial %d must be nonnegative (%d).\n", j+1, i+1, polyNumber+1, F->exponents[i][j]);
        // close file and exit
        fclose(IN);
        errExit(ERROR_INPUT_SYSTEM);
      }
      max += F->exponents[i][j];
    }

    // update degree, if needed
    if (max > F->degree)
      F->degree = max;

    // read in real & imaginary part of coefficient
    rV = mpq_inp_str(F->coeff[i]->re, IN, base);
    if (rV == 0)
    { // error in reading the coefficient
      printf("ERROR: There appears to be an error when reading in the real part of the\n       coefficient for monomial %d of polynomial %d.\n", i+1, polyNumber+1);
      // close file and exit
      fclose(IN);
      errExit(ERROR_INPUT_SYSTEM);
    } 
    rV = mpq_inp_str(F->coeff[i]->im, IN, base);
    if (rV == 0)
    { // error in reading the coefficient
      printf("ERROR: There appears to be an error when reading in the imaginary part of the\n       coefficient for monomial %d of polynomial %d.\n", i+1, polyNumber+1);
      // close file and exit
      fclose(IN);
      errExit(ERROR_INPUT_SYSTEM);
    } 

    // setup in canonical form
    mpq_canonicalize(F->coeff[i]->re);
    mpq_canonicalize(F->coeff[i]->im);

    // update isReal, if needed
    if (F->isReal && mpq_cmp_ui(F->coeff[i]->im, 0, 1) != 0)
      F->isReal = 0;
  }

  // compute norm_sqr
  norm_sqr_polynomial(F->norm_sqr, F);
  
  return;
}
Example #7
0
void setup_exponential(exponential *F, int numVars, FILE *IN, int expNumber, int yIndex)
/***************************************************************\
* USAGE: setup the next exponential described in IN             *
\***************************************************************/
{
  int rV, base = 10;

  // read in the x variable index
  rV = fscanf(IN, "%d", &F->xIndex);
  if (rV == 0)
  { // error in reading the x variable index
    printf("ERROR: There appears to be an error when reading in the variable index\n       for exponential %d.\n", expNumber+1);
    // close file and exit
    fclose(IN);
    errExit(ERROR_INPUT_SYSTEM);
  } 

  // error checking - want variable index to be in 1,2,..,numVars
  if (F->xIndex < 1 || F->xIndex > numVars)
  { // error
    printf("ERROR: The variable index for exponential %d must be between 1 and %d.\n", expNumber+1, numVars);
    // close file and exit
    fclose(IN);
    errExit(ERROR_INPUT_SYSTEM);
  }

  // setup x & y variable index
  F->xIndex--;
  F->yIndex = yIndex;

  // read in the type of exponential function: exp, sin, or cos
  rV = readInExpFunction(IN, &F->expFunction, &F->isHyperbolic);
  if (rV == 0)
  { // error in reading the exponential function
    printf("ERROR: There appears to be an error when reading in the exponential function\n       for exponential %d.\n", expNumber+1);
    // close file and exit
    fclose(IN);
    errExit(ERROR_INPUT_SYSTEM);
  } 

  // error checking
  if (F->expFunction != 'X' && F->expFunction != 'S' && F->expFunction != 'C')
  { // error
    printf("ERROR: The exponential function for exponential %d appears to be incorrect.\n", expNumber+1);
    // close file and exit
    fclose(IN);
    errExit(ERROR_INPUT_SYSTEM);
  }

  // read in real & imaginary part of beta
  initialize_rational_number(F->beta);
  rV = mpq_inp_str(F->beta->re, IN, base);
  if (rV == 0)
  { // error in reading the coefficient
    printf("ERROR: There appears to be an error when reading in the real part of the\n       exponential constant for exponential %d.\n", expNumber+1);
    // close file and exit
    fclose(IN);
    errExit(ERROR_INPUT_SYSTEM);
  } 
  rV = mpq_inp_str(F->beta->im, IN, base);
  if (rV == 0)
  { // error in reading the coefficient
    printf("ERROR: There appears to be an error when reading in the imaginary part of the\n       exponential constant exponential %d.\n", expNumber+1);
    // close file and exit
    fclose(IN);
    errExit(ERROR_INPUT_SYSTEM);
  } 

  // setup in canonical form
  mpq_canonicalize(F->beta->re);
  mpq_canonicalize(F->beta->im);

  // update isReal
  F->isReal = !mpq_cmp_ui(F->beta->im, 0, 1);

  return;
}
Example #8
0
int print_coeff(FILE *OUT, rational_complex_number z, int somethingPrinted)
/***************************************************************\
* USAGE: prints z to OUT in user-friendly way                 *
\***************************************************************/
{
  int rV = -2; // 0 if z is zero (nothing printed), 1 if z is one (nothing printed), -1 if z is -1 (nothing printed), -2 otherwise (something printed)
  int base = 10;

  if (mpq_cmp_ui(z->re, 0, 1) == 0)
  { // real part is zero
    if (mpq_cmp_ui(z->im, 0, 1) == 0)
    { // imag part is zero
      rV = 0;
    }
    else
    { // imag part is nonzero
      if (somethingPrinted && mpq_sgn(z->im) >= 0)
        fprintf(OUT, "+");

      if (mpq_cmp_ui(z->im, 1, 1) == 0)
        fprintf(OUT, "I");
      else if (mpq_cmp_si(z->im, -1, 1) == 0)
        fprintf(OUT, "-I");
      else
      {
        mpq_out_str(OUT, base, z->im);
        fprintf(OUT, "*I");
      }
    }
  }
  else
  { // real part is nonzero
    if (mpq_cmp_ui(z->im, 0, 1) == 0)
    { // imag part is zero
      if (mpq_cmp_ui(z->re, 1, 1) == 0)
      { // value is 1
        rV = 1;
      }
      else if (mpq_cmp_si(z->re, -1, 1) == 0)
      { // value is -1
        rV = -1;
      }
      else
      {
        if (somethingPrinted && mpq_sgn(z->re) >= 0)
          fprintf(OUT, "+");
        mpq_out_str(OUT, base, z->re);
      }
    }
    else
    { // imag part is nonzero
      if (somethingPrinted)
        fprintf(OUT, "+");
      fprintf(OUT, "(");
      mpq_out_str(OUT, base, z->re);
      if (mpq_sgn(z->im) >= 0)
        fprintf(OUT, "+");
      mpq_out_str(OUT, base, z->im);
      fprintf(OUT, "*I)");
    }
  }

  return rV;
}
void
check_n (void)
{
  {
    int  n = -1;
    check_one ("blah", "%nblah", &n);
    ASSERT_ALWAYS (n == 0);
  }

  {
    int  n = -1;
    check_one ("hello ", "hello %n", &n);
    ASSERT_ALWAYS (n == 6);
  }

  {
    int  n = -1;
    check_one ("hello  world", "hello %n world", &n);
    ASSERT_ALWAYS (n == 6);
  }

#define CHECK_N(type, string)                           \
  do {                                                  \
    type  x[2];                                         \
    char  fmt[128];                                     \
							\
    x[0] = ~ (type) 0;                                  \
    x[1] = ~ (type) 0;                                  \
    sprintf (fmt, "%%d%%%sn%%d", string);               \
    check_one ("123456", fmt, 123, &x[0], 456);         \
							\
    /* should write whole of x[0] and none of x[1] */   \
    ASSERT_ALWAYS (x[0] == 3);                          \
    ASSERT_ALWAYS (x[1] == (type) ~ (type) 0);		\
							\
  } while (0)

  CHECK_N (mp_limb_t, "M");
  CHECK_N (char,      "hh");
  CHECK_N (long,      "l");
#if HAVE_LONG_LONG
  CHECK_N (long long, "L");
#endif
#if HAVE_INTMAX_T
  CHECK_N (intmax_t,  "j");
#endif
#if HAVE_PTRDIFF_T
  CHECK_N (ptrdiff_t, "t");
#endif
  CHECK_N (short,     "h");
  CHECK_N (size_t,    "z");

  {
    mpz_t  x[2];
    mpz_init_set_si (x[0], -987L);
    mpz_init_set_si (x[1],  654L);
    check_one ("123456", "%d%Zn%d", 123, x[0], 456);
    MPZ_CHECK_FORMAT (x[0]);
    MPZ_CHECK_FORMAT (x[1]);
    ASSERT_ALWAYS (mpz_cmp_ui (x[0], 3L) == 0);
    ASSERT_ALWAYS (mpz_cmp_ui (x[1], 654L) == 0);
    mpz_clear (x[0]);
    mpz_clear (x[1]);
  }

  {
    mpq_t  x[2];
    mpq_init (x[0]);
    mpq_init (x[1]);
    mpq_set_ui (x[0], -987L, 654L);
    mpq_set_ui (x[1], 4115L, 226L);
    check_one ("123456", "%d%Qn%d", 123, x[0], 456);
    MPQ_CHECK_FORMAT (x[0]);
    MPQ_CHECK_FORMAT (x[1]);
    ASSERT_ALWAYS (mpq_cmp_ui (x[0], 3L, 1L) == 0);
    ASSERT_ALWAYS (mpq_cmp_ui (x[1], 4115L, 226L) == 0);
    mpq_clear (x[0]);
    mpq_clear (x[1]);
  }

  {
    mpf_t  x[2];
    mpf_init (x[0]);
    mpf_init (x[1]);
    mpf_set_ui (x[0], -987L);
    mpf_set_ui (x[1],  654L);
    check_one ("123456", "%d%Fn%d", 123, x[0], 456);
    MPF_CHECK_FORMAT (x[0]);
    MPF_CHECK_FORMAT (x[1]);
    ASSERT_ALWAYS (mpf_cmp_ui (x[0], 3L) == 0);
    ASSERT_ALWAYS (mpf_cmp_ui (x[1], 654L) == 0);
    mpf_clear (x[0]);
    mpf_clear (x[1]);
  }

  {
    mp_limb_t  a[5];
    mp_limb_t  a_want[numberof(a)];
    mp_size_t  i;

    a[0] = 123;
    check_one ("blah", "bl%Nnah", a, (mp_size_t) 0);
    ASSERT_ALWAYS (a[0] == 123);

    MPN_ZERO (a_want, numberof (a_want));
    for (i = 1; i < numberof (a); i++)
      {
	check_one ("blah", "bl%Nnah", a, i);
	a_want[0] = 2;
	ASSERT_ALWAYS (mpn_cmp (a, a_want, i) == 0);
      }
  }
}
Example #10
0
int sqrt_upper(mpq_t sqrt_x, mpq_t x, int digits)
/***************************************************************\
* USAGE: compute a certified rational upper bound on the sqrt(x)*
*    that is within 10^-digits of the true value 0-good,1-error *
\***************************************************************/
{
  int rV = 0, sign = mpq_sgn(x);

  // verify digits >= 0
  if (digits < 0)
  { // error
    printf("ERROR: The number of digits must be nonnegative!\n");
    errExit(ERROR_CONFIGURATION);
  }

  // check the sign of x
  if (sign == -1)
  { // x is negative - return error
    rV = 1;
  }
  else if (sign == 0)
  { // x is zero - sqrt(x) = 0
    mpq_set_ui(sqrt_x, 0, 1);
    rV = 0;
  }
  else
  { // x is positive - compute sqrt(x)
    int prec;
    mpfr_t sqrt_x_float;
    mpf_t tempMPF;
    mpq_t sqrt_x_temp, tempMPQ;

    // determine the precision to use to get an approximation
    if (digits <= 16)
      prec = 64;
    else
    { // determine the precision needed
      prec = (int) ceil((digits + 0.5) / (32 * log10(2.0)));
      if (prec <= 2)
        prec = 64;
      else
        prec *= 32;
    }

    // initialize
    mpfr_init2(sqrt_x_float, prec);
    mpf_init2(tempMPF, prec);
    mpq_init(sqrt_x_temp);
    mpq_init(tempMPQ);
    
    // approximate sqrt(x) - round up!
    mpfr_set_q(sqrt_x_float, x, GMP_RNDU);
    mpfr_sqrt(sqrt_x_float, sqrt_x_float, GMP_RNDU);

    // convert to rational
    mpfr_get_f(tempMPF, sqrt_x_float, GMP_RNDU);
    mpq_set_f(sqrt_x_temp, tempMPF);

    // verify that sqrt_x_temp is an upper bound 
    mpq_mul(tempMPQ, sqrt_x_temp, sqrt_x_temp);
    if (mpq_cmp(tempMPQ, x) >= 0)
    { // we have an upper bound - refine & certify it
      refine_sqrt_upper(sqrt_x_temp, x, digits);
      // copy to sqrt_x
      mpq_set(sqrt_x, sqrt_x_temp);
      rV = 0;
    }
    else
    { // try again with 2*x (Newton iterations still converge quadratically!)
      mpq_add(tempMPQ, x, x);
      mpfr_set_q(sqrt_x_float, tempMPQ, GMP_RNDU);
      mpfr_sqrt(sqrt_x_float, sqrt_x_float, GMP_RNDU);

      // convert to rational
      mpfr_get_f(tempMPF, sqrt_x_float, GMP_RNDU);
      mpq_set_f(sqrt_x_temp, tempMPF);

      // verify that sqrt_x_temp is an upper bound 
      mpq_mul(tempMPQ, sqrt_x_temp, sqrt_x_temp);
      if (mpq_cmp(tempMPQ, x) >= 0)
      { // we have an upper bound - refine & certify it
        refine_sqrt_upper(sqrt_x_temp, x, digits);
        // copy to sqrt_x
        mpq_set(sqrt_x, sqrt_x_temp);
        rV = 0;
      }
      else
      { // take any upper bound
        if (mpq_cmp_ui(x, 1, 1) <= 0)
        { // 1 is an upper bound for sqrt(x)
          mpq_set_ui(sqrt_x_temp, 1, 1);
        }
        else
        { // x is an upper bound for sqrt(x)
          mpq_set(sqrt_x_temp, x);
        }
        // we have an upper bound - refine & certify it
        refine_sqrt_upper(sqrt_x_temp, x, digits);
        // copy to sqrt_x
        mpq_set(sqrt_x, sqrt_x_temp);
        rV = 0;
      }
    }

    // clear
    mpfr_clear(sqrt_x_float);
    mpf_clear(tempMPF);
    mpq_clear(sqrt_x_temp);
    mpq_clear(tempMPQ);
  }

  return rV;
}