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:; }
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); } }
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); }
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); }
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; }
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; }
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); } } }
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; }