int promoteToMPZNumber(number *n) { switch(n->type) { case V_INTEGER: mpz_init_set_si64(n->value.mpz, n->value.i); n->type = V_MPZ; break; case V_MPZ: break; case V_MPQ: { mpz_t mpz; mpz_init(mpz); mpz_tdiv_q(mpz, mpq_numref(n->value.mpq), mpq_denref(n->value.mpq)); clearNumber(n); n->type = V_MPZ; n->value.mpz[0] = mpz[0]; break; } case V_FLOAT: mpz_init_set_d(n->value.mpz, n->value.f); n->type = V_MPZ; break; } return TRUE; }
static CBIGINT *_divf(CBIGINT *a, double f, bool invert) { if (invert) { CBIGINT *b; mpz_t n; mpz_init_set_d(n, f); b = BIGINT_create(n); return _div(b, a, FALSE); } else { if (f > 0) { return BIGINT_make_int(a, f, mpz_tdiv_q_ui); } else if (f < 0) { a = BIGINT_make_int(a, (-f), mpz_tdiv_q_ui); mpz_neg(a->n, a->n); return a; } else { GB.Error(GB_ERR_ZERO); return NULL; } } }
obj float_to_bignum(obj X) { IEEE_64 x = extract_float(X); mpz_t a; mpz_init_set_d(a, x); return mpz_to_bignum(a); }
void check_data (void) { static const struct { double d; mp_size_t want_size; mp_limb_t want_data[2]; } data[] = { { 0.0, 0 }, { 1.0, 1, { 1 } }, { -1.0, -1, { 1 } }, { 123.0, 1, { 123 } }, { -123.0, -1, { 123 } }, }; mpz_t z; int i; for (i = 0; i < numberof (data); i++) { mpz_init (z); mpz_set_d (z, data[i].d); MPZ_CHECK_FORMAT (z); if (z->_mp_size != data[i].want_size || refmpn_cmp_allowzero (z->_mp_d, data[i].want_data, ABS (data[i].want_size)) != 0) { printf ("mpz_set_d wrong on data[%d]\n", i); bad: d_trace (" d ", data[i].d); printf (" got size %ld\n", (long) z->_mp_size); printf (" want size %ld\n", (long) data[i].want_size); mpn_trace (" got z", z->_mp_d, z->_mp_size); mpn_trace (" want z", data[i].want_data, data[i].want_size); abort(); } mpz_clear (z); mpz_init_set_d (z, data[i].d); MPZ_CHECK_FORMAT (z); if (z->_mp_size != data[i].want_size || refmpn_cmp_allowzero (z->_mp_d, data[i].want_data, ABS (data[i].want_size)) != 0) { printf ("mpz_init_set_d wrong on data[%d]\n", i); goto bad; } mpz_clear (z); } }
mpz_int(double op) { mpz_init_set_d(m_data, op); }
int main(int argc, char **argv) { int my_rank; int num_procs; int source; int dest; long long bound = 1000000000000000; double largest_diff = 0; double temp_diff = 0; MPI_Status status; //initialize MPI MPI_Init(&argc, &argv); // start mpi MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); // process rank MPI_Comm_size(MPI_COMM_WORLD, &num_procs); // find out the number of process MPI_Barrier(MPI_COMM_WORLD); double elapsed_time = -MPI_Wtime(); //calculate chunk size per processor and the remainder long long int chunk = floor(bound/num_procs); long long int r = fmod(bound, num_procs); //determine the starting index for a given processor and the next long long index = my_rank * chunk + MIN(my_rank, r); long long next_start_index = (my_rank + 1) * chunk + MIN((my_rank + 1), r); long long i = index; //initialize mpz types mpz_t key_prime_1; mpz_init_set_d(key_prime_1, 2); mpz_t key_prime_2; mpz_init_set_d(key_prime_2, 2); mpz_t m_index; mpz_init_set_d(m_index, index); mpz_t diff; mpz_init(diff); mpz_t prev_prime; mpz_init(prev_prime); mpz_t curr_prime; mpz_init(curr_prime); printf("My rank: %d \t %.0lli \t STARTING INDEX\n", my_rank, index); mpz_nextprime(prev_prime, m_index); mpz_set(curr_prime, prev_prime); i = mpz_get_d(prev_prime) + 1; //loop getting primes and calculating differences until the prime is //outside of this processor's chunk size while (i < next_start_index) { //subtract current prime from previous mpz_sub(diff, curr_prime, prev_prime); temp_diff = mpz_get_d(diff); //if this is the largest difference, store it if (temp_diff > largest_diff) { mpz_set(key_prime_1, prev_prime); mpz_set(key_prime_2, curr_prime); largest_diff = temp_diff; } //if this is the largest difference, store it if (temp_diff > largest_diff) { largest_diff = temp_diff; } //set the previous prime to the current and get the next prime mpz_set(prev_prime, curr_prime); mpz_nextprime(curr_prime, prev_prime); i = mpz_get_d(curr_prime) + 1; } //subtract the previous prime from the current to get difference mpz_sub(diff, curr_prime, prev_prime); temp_diff = mpz_get_d(diff); //if this is the largest difference, store it if (temp_diff > largest_diff) { mpz_set(key_prime_1, prev_prime); mpz_set(key_prime_2, curr_prime); largest_diff = temp_diff; } //print data printf("My rank: %d \t ", my_rank); gmp_printf("%Zd \t LAST PRIME\n", prev_prime); printf("My rank: %d \t %.0f \t LARGEST DIFF\n", my_rank, largest_diff); //if this is proc 0, listen for differences from other procs if (my_rank == 0) { double proc_diff; long long prime_1 = mpz_get_d(key_prime_1); long long prime_2 = mpz_get_d(key_prime_2); long long tmp_prime_1 = 0; long long tmp_prime_2 = 0; //get difference from each proc and determine largest for (source = 1; source < num_procs; source++) { MPI_Recv(&proc_diff, 1, MPI_DOUBLE, source, 0, MPI_COMM_WORLD, &status); MPI_Recv(&tmp_prime_1, 1, MPI_LONG_LONG, source, 1, MPI_COMM_WORLD, &status); MPI_Recv(&tmp_prime_2, 1, MPI_LONG_LONG, source, 2, MPI_COMM_WORLD, &status); if (proc_diff > largest_diff) { prime_1 = tmp_prime_1; prime_2 = tmp_prime_2; largest_diff = proc_diff; } } //print data printf("FINAL LARGEST DIFF: %.0f \t between: %.0lli and %.0lli\n", largest_diff, prime_1, prime_2); } else { long long prime_1 = mpz_get_d(key_prime_1); long long prime_2 = mpz_get_d(key_prime_2); MPI_Send(&largest_diff, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD); MPI_Send(&prime_1, 1, MPI_LONG_LONG, 0, 1, MPI_COMM_WORLD); MPI_Send(&prime_2, 1, MPI_LONG_LONG, 0, 2, MPI_COMM_WORLD); } elapsed_time = MPI_Wtime(); printf("It took %lf\n", elapsed_time); MPI_Finalize(); }
static bool _convert(CBIGINT *a, GB_TYPE type, GB_VALUE *conv) { if (a) { switch (type) { case GB_T_FLOAT: conv->_float.value = mpz_get_d(a->n); return FALSE; case GB_T_SINGLE: conv->_single.value = mpz_get_d(a->n); return FALSE; case GB_T_INTEGER: case GB_T_SHORT: case GB_T_BYTE: conv->_integer.value = (int)mpz_get_si(a->n); return FALSE; case GB_T_LONG: conv->_long.value = (int64_t)mpz_get_si(a->n); return FALSE; case GB_T_STRING: case GB_T_CSTRING: conv->_string.value.addr = BIGINT_to_string(a->n, 10); //, type == GB_T_CSTRING); conv->_string.value.start = 0; conv->_string.value.len = GB.StringLength(conv->_string.value.addr); return FALSE; default: return TRUE; } } else { mpz_t n; switch(type) { case GB_T_FLOAT: mpz_init_set_d(n, conv->_float.value); conv->_object.value = BIGINT_create(n); return FALSE; case GB_T_SINGLE: mpz_init_set_d(n, conv->_single.value); conv->_object.value = BIGINT_create(n); return FALSE; case GB_T_INTEGER: case GB_T_SHORT: case GB_T_BYTE: mpz_init_set_si(n, (long)conv->_integer.value); conv->_object.value = BIGINT_create(n); return FALSE; case GB_T_LONG: mpz_init_set_si(n, (long)conv->_long.value); conv->_object.value = BIGINT_create(n); return FALSE; case GB_T_STRING: case GB_T_CSTRING: conv->_object.value = BIGINT_from_string(GB.ToZeroString(&conv->_string), 10); return conv->_object.value == NULL; default: return TRUE; } } }
void testmain (int argc, char **argv) { unsigned i; mpz_t x; for (i = 0; values[i].s; i++) { char *s; mpz_init_set_d (x, values[i].d); s = mpz_get_str (NULL, 16, x); if (strcmp (s, values[i].s) != 0) { fprintf (stderr, "mpz_set_d failed:\n" "d = %.20g\n" "s = %s\n" "r = %s\n", values[i].d, s, values[i].s); abort (); } testfree (s); mpz_clear (x); } mpz_init (x); for (i = 0; i < COUNT; i++) { /* Use volatile, to avoid extended precision in floating point registers, e.g., on m68k and 80387. */ volatile double d, f; unsigned long m; int e; mini_rrandomb (x, GMP_LIMB_BITS); m = mpz_get_ui (x); mini_urandomb (x, 8); e = mpz_get_ui (x) - 100; d = ldexp ((double) m, e); mpz_set_d (x, d); f = mpz_get_d (x); if (f != floor (d)) { fprintf (stderr, "mpz_set_d/mpz_get_d failed:\n"); goto dumperror; } if ((f == d) ? (mpz_cmp_d (x, d) != 0) : (mpz_cmp_d (x, d) >= 0)) { fprintf (stderr, "mpz_cmp_d (x, d) failed:\n"); goto dumperror; } f = d + 1.0; if (f > d && ! (mpz_cmp_d (x, f) < 0)) { fprintf (stderr, "mpz_cmp_d (x, f) failed:\n"); goto dumperror; } d = - d; mpz_set_d (x, d); f = mpz_get_d (x); if (f != ceil (d)) { fprintf (stderr, "mpz_set_d/mpz_get_d failed:\n"); dumperror: dump ("x", x); fprintf (stderr, "m = %lx, e = %i\n", m, e); fprintf (stderr, "d = %.15g\n", d); fprintf (stderr, "f = %.15g\n", f); fprintf (stderr, "f - d = %.5g\n", f - d); abort (); } if ((f == d) ? (mpz_cmp_d (x, d) != 0) : (mpz_cmp_d (x, d) <= 0)) { fprintf (stderr, "mpz_cmp_d (x, d) failed:\n"); goto dumperror; } f = d - 1.0; if (f < d && ! (mpz_cmp_d (x, f) > 0)) { fprintf (stderr, "mpz_cmp_d (x, f) failed:\n"); goto dumperror; } } mpz_clear (x); }
static bool variantToGMPData(const char* fnCaller, mpz_t gmpData, const Variant& data, int64_t base = 0, bool canBeEmptyStr = false) { switch (data.getType()) { case KindOfResource: { auto gmpRes = data.toResource().getTyped<GMPResource>(false, true); if (!gmpRes) { raise_warning(cs_GMP_INVALID_RESOURCE, fnCaller); return false; } mpz_init_set(gmpData, gmpRes->getData()); return true; } case KindOfString: case KindOfStaticString: { String strNum = data.toString(); int64_t strLength = strNum.length(); if (strLength == 0) { if (canBeEmptyStr) { mpz_init_set_si(gmpData, 0); return true; } else { return false; } } bool isNegative; String negativeSign; if (strNum[0] == '-') { isNegative = true; negativeSign = "-"; } else if (strNum[0] == '+') { /* Our "isNumeric" function considers '+' a valid lead to a number, * php does not agree. */ return false; } else { isNegative = false; negativeSign = ""; } /* Figure out what base to use based on the data. * * We can't rely on GMP's auto-base detection as it doesn't handle cases * where a base is specified AND a prefix is specified. So, we strip out * all prefixes and detect the bases ourselves. */ if (strLength > (isNegative + 2) && strNum[isNegative] == '0') { if ((base == 0 || base == 16) && (strNum[isNegative + 1] == 'x' || strNum[isNegative + 1] == 'X')) { base = 16; strNum = negativeSign + strNum.substr(isNegative + 2); } else if ((base == 0 || base == 2) && (strNum[isNegative + 1] == 'b' || strNum[isNegative + 1] == 'B')) { base = 2; strNum = negativeSign + strNum.substr(isNegative + 2); } else if (base == 0 || base == 8) { base = 8; strNum = negativeSign + strNum.substr(isNegative + 1); } } if (mpz_init_set_str(gmpData, strNum.c_str(), base) == -1) { mpz_clear(gmpData); if (base == 0 && strNum.get()->isNumeric()) { mpz_init_set_si(gmpData, strNum.toInt64()); } else { return false; } } return true; } case KindOfInt64: case KindOfBoolean: mpz_init_set_si(gmpData, data.toInt64()); return true; case KindOfDouble: if (data.toDouble() > DBL_MAX || data.toDouble() < DBL_MIN) { raise_warning(cs_GMP_INVALID_TYPE, fnCaller); return false; } mpz_init_set_d(gmpData, data.toDouble()); return true; default: raise_warning(cs_GMP_INVALID_TYPE, fnCaller); return false; } }
int main (int argc, char *argv[]) { const char usage[] = "usage: findlc [-dv] m2exp [low_merit [high_merit]]\n"; int f; int v_lose, m_lose, v_best, m_best; int c; int debug = 1; int cnt_high_merit; mpz_t m; unsigned long int m2exp; #define DIMS 6 /* dimensions run in spectral test */ mpf_t v[DIMS-1]; /* spectral test result (there's no v for 1st dimension */ mpf_t f_merit, low_merit, high_merit; mpz_t acc, minus8; mpz_t min, max; mpz_t s; mpz_init (m); mpz_init (a); for (f = 0; f < DIMS-1; f++) mpf_init (v[f]); mpf_init (f_merit); mpf_init_set_d (low_merit, .1); mpf_init_set_d (high_merit, .1); while ((c = getopt (argc, argv, "a:di:hv")) != -1) switch (c) { case 'd': /* debug */ g_debug++; break; case 'v': /* print version */ puts (rcsid[1]); exit (0); case 'h': case '?': default: fputs (usage, stderr); exit (1); } argc -= optind; argv += optind; if (argc < 1) { fputs (usage, stderr); exit (1); } /* Install signal handler. */ if (SIG_ERR == signal (SIGSEGV, sh_status)) { perror ("signal (SIGSEGV)"); exit (1); } if (SIG_ERR == signal (SIGHUP, sh_status)) { perror ("signal (SIGHUP)"); exit (1); } printf ("findlc: version: %s\n", rcsid[1]); m2exp = atol (argv[0]); mpz_init_set_ui (m, 1); mpz_mul_2exp (m, m, m2exp); printf ("m = 0x"); mpz_out_str (stdout, 16, m); puts (""); if (argc > 1) /* have low_merit */ mpf_set_str (low_merit, argv[1], 0); if (argc > 2) /* have high_merit */ mpf_set_str (high_merit, argv[2], 0); if (debug) { fprintf (stderr, "low_merit = "); mpf_out_str (stderr, 10, 2, low_merit); fprintf (stderr, "; high_merit = "); mpf_out_str (stderr, 10, 2, high_merit); fputs ("\n", stderr); } mpz_init (minus8); mpz_set_si (minus8, -8L); mpz_init_set_ui (acc, 0); mpz_init (s); mpz_init_set_d (min, 0.01 * pow (2.0, (double) m2exp)); mpz_init_set_d (max, 0.99 * pow (2.0, (double) m2exp)); mpz_true_random (s, m2exp); /* Start. */ mpz_setbit (s, 0); /* Make it odd. */ v_best = m_best = 2*(DIMS-1); for (;;) { mpz_add (acc, acc, s); mpz_mod_2exp (acc, acc, m2exp); #if later mpz_and_si (a, acc, -8L); #else mpz_and (a, acc, minus8); #endif mpz_add_ui (a, a, 5); if (mpz_cmp (a, min) <= 0 || mpz_cmp (a, max) >= 0) continue; spectral_test (v, DIMS, a, m); for (f = 0, v_lose = m_lose = 0, cnt_high_merit = DIMS-1; f < DIMS-1; f++) { merit (f_merit, f + 2, v[f], m); if (mpf_cmp_ui (v[f], 1 << (30 / (f + 2) + (f == 2))) < 0) v_lose++; if (mpf_cmp (f_merit, low_merit) < 0) m_lose++; if (mpf_cmp (f_merit, high_merit) >= 0) cnt_high_merit--; } if (0 == v_lose && 0 == m_lose) { mpz_out_str (stdout, 10, a); puts (""); fflush (stdout); if (0 == cnt_high_merit) break; /* leave loop */ } if (v_lose < v_best) { v_best = v_lose; printf ("best (v_lose=%d; m_lose=%d): ", v_lose, m_lose); mpz_out_str (stdout, 10, a); puts (""); fflush (stdout); } if (m_lose < m_best) { m_best = m_lose; printf ("best (v_lose=%d; m_lose=%d): ", v_lose, m_lose); mpz_out_str (stdout, 10, a); puts (""); fflush (stdout); } } mpz_clear (m); mpz_clear (a); for (f = 0; f < DIMS-1; f++) mpf_clear (v[f]); mpf_clear (f_merit); mpf_clear (low_merit); mpf_clear (high_merit); printf ("done.\n"); return 0; }
extern "C" PyObject* PyLong_FromDouble(double v) noexcept { BoxedLong* rtn = new BoxedLong(); mpz_init_set_d(rtn->n, v); return rtn; }
obj raw_float_to_bignum(IEEE_64 x) { mpz_t a; mpz_init_set_d(a, x); return mpz_to_bignum(a); }