float_::type float_::operator()(__gmp_expr<T, U> const &a) { return mpz_get_d(a.get_mpz_t()); }
static int pol_expand(curr_poly_t *c, mpz_t gmp_N, mpz_t high_coeff, mpz_t gmp_p, mpz_t gmp_d, double coeff_bound, uint32 degree) { uint32 i, j; if (mpz_cmp_ui(c->gmp_p, (mp_limb_t)1) == 0) mpz_set_ui(c->gmp_help1, (mp_limb_t)1); else { if (!mpz_invert(c->gmp_help1, gmp_d, gmp_p)) return 0; } mpz_set(c->gmp_b[1], c->gmp_help1); for (i = 2; i < degree; i++) mpz_mul(c->gmp_b[i], c->gmp_b[i-1], c->gmp_help1); mpz_set(c->gmp_c[1], gmp_d); for (i = 2; i <= degree; i++) mpz_mul(c->gmp_c[i], c->gmp_c[i-1], gmp_d); mpz_set(c->gmp_a[degree], high_coeff); mpz_set(c->gmp_help2, gmp_N); for (i = degree - 1; (int32)i >= 0; i--) { mpz_mul(c->gmp_help3, c->gmp_a[i+1], c->gmp_c[i+1]); mpz_sub(c->gmp_help3, c->gmp_help2, c->gmp_help3); mpz_tdiv_q(c->gmp_help2, c->gmp_help3, gmp_p); if (i > 0) { mpz_tdiv_q(c->gmp_a[i], c->gmp_help2, c->gmp_c[i]); mpz_mul(c->gmp_help3, c->gmp_help2, c->gmp_b[i]); mpz_sub(c->gmp_help3, c->gmp_help3, c->gmp_a[i]); mpz_tdiv_r(c->gmp_help4, c->gmp_help3, gmp_p); if (mpz_sgn(c->gmp_help4) < 0) mpz_add(c->gmp_help4, c->gmp_help4, gmp_p); mpz_add(c->gmp_a[i], c->gmp_a[i], c->gmp_help4); } } mpz_set(c->gmp_a[0], c->gmp_help2); mpz_tdiv_q_2exp(c->gmp_help1, gmp_d, (mp_limb_t)1); for (i = 0; i < degree; i++) { for (j = 0; j < MAX_CORRECT_STEPS && mpz_cmpabs(c->gmp_a[i], c->gmp_help1) > 0; j++) { if (mpz_sgn(c->gmp_a[i]) < 0) { mpz_add(c->gmp_a[i], c->gmp_a[i], gmp_d); mpz_sub(c->gmp_a[i+1], c->gmp_a[i+1], gmp_p); } else { mpz_sub(c->gmp_a[i], c->gmp_a[i], gmp_d); mpz_add(c->gmp_a[i+1], c->gmp_a[i+1], gmp_p); } } if (j == MAX_CORRECT_STEPS) return 0; } #if 0 gmp_printf("%+Zd\n", c->gmp_lina[0]); gmp_printf("%+Zd\n", c->gmp_lina[1]); for (i = 0; i <= degree; i++) gmp_printf("%+Zd\n", c->gmp_a[i]); printf("coeff ratio = %.5lf\n", fabs(mpz_get_d(c->gmp_a[degree-2])) / coeff_bound); #endif if (check_poly(c, c->gmp_a, c->gmp_lina[0], gmp_N, degree) != 1) { return 0; } if (mpz_cmpabs_d(c->gmp_a[degree - 2], coeff_bound) > 0) { return 1; } return 2; }
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); }
template<> void SET_INTOBJ(Z_NR<double> &v, Obj z) { if (IS_INTOBJ(z)) v = INT_INTOBJ(z); else v = mpz_get_d(mpz_MPZ(MPZ_LONGINT(z))); }
void set_from_mpz(ElementType &result, mpz_ptr a) const { result.re = mpz_get_d(a); result.im = 0.0; }
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 void search_coeffs(msieve_obj *obj, poly_search_t *poly, bounds_t *bounds, uint32 deadline) { mpz_t curr_high_coeff; double dn = mpz_get_d(poly->N); uint32 digits = mpz_sizeinbase(poly->N, 10); double start_time = get_cpu_time(); uint32 deadline_per_coeff = 800; uint32 batch_size = (poly->degree == 5) ? POLY_BATCH_SIZE : 1; if (digits <= 100) deadline_per_coeff = 5; else if (digits <= 105) deadline_per_coeff = 20; else if (digits <= 110) deadline_per_coeff = 30; else if (digits <= 120) deadline_per_coeff = 50; else if (digits <= 130) deadline_per_coeff = 100; else if (digits <= 140) deadline_per_coeff = 200; else if (digits <= 150) deadline_per_coeff = 400; printf("deadline: %u seconds per coefficient\n", deadline_per_coeff); mpz_init(curr_high_coeff); mpz_fdiv_q_ui(curr_high_coeff, bounds->gmp_high_coeff_begin, (mp_limb_t)MULTIPLIER); mpz_mul_ui(curr_high_coeff, curr_high_coeff, (mp_limb_t)MULTIPLIER); if (mpz_cmp(curr_high_coeff, bounds->gmp_high_coeff_begin) < 0) { mpz_add_ui(curr_high_coeff, curr_high_coeff, (mp_limb_t)MULTIPLIER); } poly->num_poly = 0; while (1) { curr_poly_t *c = poly->batch + poly->num_poly; if (mpz_cmp(curr_high_coeff, bounds->gmp_high_coeff_end) > 0) { if (poly->num_poly > 0) { search_coeffs_core(obj, poly, deadline_per_coeff); } break; } stage1_bounds_update(bounds, dn, mpz_get_d(curr_high_coeff), poly->degree); mpz_set(c->high_coeff, curr_high_coeff); c->p_size_max = bounds->p_size_max; c->coeff_max = bounds->coeff_max; if (++poly->num_poly == batch_size) { search_coeffs_core(obj, poly, deadline_per_coeff); if (obj->flags & MSIEVE_FLAG_STOP_SIEVING) break; if (deadline) { double curr_time = get_cpu_time(); double elapsed = curr_time - start_time; if (elapsed > deadline) break; } poly->num_poly = 0; } mpz_add_ui(curr_high_coeff, curr_high_coeff, (mp_limb_t)MULTIPLIER); } mpz_clear(curr_high_coeff); }
double float_(__gmp_expr<T,U> const& a) { return mpz_get_d(a.get_mpz_t()); }
void ovm_q_atan2(oregister_t *l, oregister_t *r) { switch (r->t) { case t_void: if (!cfg_float_format) { l->t = t_float; l->v.d = atan2(mpq_get_d(oqr(l)), 0.0); } else { mpfr_set_ui(orr(r), 0, thr_rnd); goto mpr; } break; case t_word: if (!cfg_float_format) { l->t = t_float; l->v.d = atan2(mpq_get_d(oqr(l)), r->v.w); } else { mpfr_set_si(orr(r), r->v.w, thr_rnd); goto mpr; } break; case t_float: l->t = t_float; l->v.d = atan2(mpq_get_d(oqr(l)), r->v.d); break; case t_mpz: if (!cfg_float_format) { l->t = t_float; l->v.d = atan2(mpq_get_d(oqr(l)), mpz_get_d(ozr(r))); } else { mpfr_set_z(orr(r), ozr(r), thr_rnd); goto mpr; } break; case t_rat: if (!cfg_float_format) { l->t = t_float; l->v.d = atan2(mpq_get_d(oqr(l)), rat_get_d(r->v.r)); } else { mpq_set_si(oqr(r), rat_num(r->v.r), rat_den(r->v.r)); mpfr_set_q(orr(r), oqr(r), thr_rnd); goto mpr; } break; case t_mpq: if (!cfg_float_format) { l->t = t_float; l->v.d = atan2(mpq_get_d(oqr(l)), mpq_get_d(oqr(r))); } else { mpfr_set_q(orr(r), oqr(r), thr_rnd); goto mpr; } break; case t_mpr: mpr: mpfr_set_q(orr(l), oqr(l), thr_rnd); l->t = t_mpr; mpfr_atan2(orr(l), orr(l), orr(r), thr_rnd); break; case t_cdd: cdd: l->t = t_cdd; real(l->v.dd) = mpq_get_d(oqr(l)); imag(l->v.dd) = 0.0; l->v.dd = catan(l->v.dd / r->v.dd); check_cdd(l); break; case t_cqq: if (!cfg_float_format) { real(r->v.dd) = mpq_get_d(oqr(r)); imag(r->v.dd) = mpq_get_d(oqi(r)); goto cdd; } mpc_set_q_q(occ(r), oqr(r), oqi(r), thr_rndc); case t_mpc: l->t = t_mpc; mpc_set_q(occ(l), oqr(l), thr_rndc); mpc_div(occ(l), occ(l), occ(r), thr_rndc); mpc_atan(occ(l), occ(l), thr_rndc); check_mpc(l); break; default: ovm_raise(except_not_a_number); } }
extern "C" double PyLong_AsDouble(PyObject* vv) noexcept { RELEASE_ASSERT(PyLong_Check(vv), ""); BoxedLong* l = static_cast<BoxedLong*>(vv); return mpz_get_d(l->n); }
void set_from_mpz(ElementType &result, mpz_ptr a) const { result = mpz_get_d(a); }
void ocoerce(oobject_t *pointer, otype_t type, oobject_t value) { union { oint64_t i; ofloat32_t f; ofloat_t d; } data; switch (type) { case t_int8: case t_uint8: case t_int16: case t_uint16: case t_int32: case t_uint32: case t_int64: case t_uint64: switch (otype(value)) { case t_word: data.i = *(oword_t *)value; break; case t_float: data.i = *(ofloat_t *)value; break; case t_mpz: data.i = ompz_get_sl((ompz_t)value); break; case t_mpq: data.i = ompq_get_sl((ompq_t)value); break; case t_mpr: data.i = ompr_get_sl((ompr_t)value); break; case t_cdd: data.i = real(*(ocdd_t *)value); break; case t_cqq: data.i = ompq_get_sl(cqq_realref((ocqq_t)value)); break; default: assert(otype(value) == t_mpc); data.i = ompr_get_sl(mpc_realref((ompc_t)value)); break; } break; case t_float32: case t_float64: switch (otype(value)) { case t_word: data.d = *(oword_t *)value; break; case t_float: data.d = *(ofloat_t *)value; break; case t_mpz: data.d = mpz_get_d((ompz_t)value); break; case t_mpq: data.d = mpq_get_d((ompq_t)value); break; case t_mpr: data.d = mpfr_get_d((ompr_t)value, thr_rnd); break; case t_cdd: data.d = real(*(ocdd_t *)value); break; case t_cqq: data.d = mpq_get_d(cqq_realref((ocqq_t)value)); break; default: assert(otype(value) == t_mpc); data.i = mpfr_get_d(mpc_realref((ompc_t)value), thr_rnd); break; } break; default: data.i = 0; break; } switch (type) { case t_int8: oget_word(pointer); pointer = *pointer; *(oword_t *)pointer = (oint8_t)data.i; break; case t_uint8: oget_word(pointer); pointer = *pointer; *(oword_t *)pointer = (ouint8_t)data.i; break; case t_int16: oget_word(pointer); pointer = *pointer; *(oword_t *)pointer = (oint16_t)data.i; break; case t_uint16: oget_word(pointer); pointer = *pointer; *(oword_t *)pointer = (ouint16_t)data.i; break; case t_int32: oget_word(pointer); pointer = *pointer; *(oword_t *)pointer = (oint32_t)data.i; break; case t_uint32: #if __WORDSIZE == 32 if ((ouword_t)data.i != data.i) { oget_mpz(pointer); pointer = *pointer; mpz_set_ui((ompz_t)pointer, (ouword_t)data.i); } else #endif { oget_word(pointer); pointer = *pointer; *(oword_t *)pointer = (ouint32_t)data.i; } break; case t_int64: #if __WORDSIZE == 32 if ((oword_t)data.i != data.i) { oget_mpz(pointer); pointer = *pointer; ompz_set_sl((ompz_t)pointer, data.i); } else #endif { oget_word(pointer); pointer = *pointer; *(oword_t *)pointer = (oword_t)data.i; } break; case t_uint64: if ((ouword_t)data.i != data.i) { oget_mpz(pointer); pointer = *pointer; mpz_set_ui((ompz_t)pointer, (ouword_t)data.i); } else { oget_word(pointer); pointer = *pointer; *(oword_t *)pointer = (ouword_t)data.i; } break; case t_float32: data.f = data.d; data.d = data.f; case t_float: oget_float(pointer); pointer = *pointer; *(ofloat_t *)pointer = data.d; break; default: ocopy(pointer, value); break; } }
/*------------------------------------------------------------------------*/ static int find_next_ad(sieve_t *sieve, poly_search_t *poly, mpz_t next_coeff) { uint32 i, j, p, k; double td_test; uint8 *sieve_array = sieve->sieve_array; while (1) { for (i = sieve->curr_offset; i < SIEVE_ARRAY_SIZE; i++) { if (!(sieve_array[i] & 0x80)) continue; mpz_divexact_ui(poly->tmp1, poly->gmp_high_coeff_begin, HIGH_COEFF_MULTIPLIER); mpz_add_ui(poly->tmp1, poly->tmp1, i); mpz_mul_ui(next_coeff, poly->tmp1, HIGH_COEFF_MULTIPLIER); if (mpz_cmp(next_coeff, poly->gmp_high_coeff_end) > 0) break; /* trial divide the a_d and skip it if it does not have enough small factors */ td_test = ceil(mpz_get_d(poly->tmp1) / HIGH_COEFF_SIEVE_LIMIT); for (j = p = 0; j < PRECOMPUTED_NUM_PRIMES; j++) { p += prime_delta[j]; if (p > HIGH_COEFF_PRIME_LIMIT) break; for (k = 0; k < HIGH_COEFF_POWER_LIMIT; k++) { if (mpz_divisible_ui_p(poly->tmp1, p)) mpz_divexact_ui(poly->tmp1, poly->tmp1, p); else break; } } if (mpz_get_d(poly->tmp1) > td_test) continue; /* a_d is okay, search it */ sieve->curr_offset = i + 1; return 0; } /* update lower bound for next sieve block */ mpz_set_ui(poly->tmp1, SIEVE_ARRAY_SIZE); mpz_mul_ui(poly->tmp1, poly->tmp1, HIGH_COEFF_MULTIPLIER); mpz_add(poly->gmp_high_coeff_begin, poly->gmp_high_coeff_begin, poly->tmp1); if (mpz_cmp(poly->gmp_high_coeff_begin, poly->gmp_high_coeff_end) > 0) break; sieve->curr_offset = 0; sieve_ad_block(sieve, poly); } return 1; }
void find_candidates(mpz_t num, mpz_t gmp_root) { num_cands = 0; mpz_add_ui(gmp_root, gmp_root, 1); size_t sieve_size = primes[B-1]*100; double *table = malloc(sizeof(double)*sieve_size); uint64_t root = mpz_get_ui(gmp_root); double approx = mpz_get_d(num); mpz_t tmp, tmp2; mpz_init(tmp); mpz_init(tmp2); mpz_set_ui(tmp, root); mpz_pow_ui(tmp, tmp, 2); mpz_sub(tmp, tmp, num); mpz_set(first_cands[0], tmp); unsigned int used_primes[B]; double used_log[B]; used_primes[0] = 2; used_log[0] = log_primes[0]; size_t next_prime = 1; size_t offsets[B][2]; uint64_t cand_offsets[B+1]; size_t next_cand = 1; // Find prime numbers that appear in the candidate series for(size_t p = 1; p < B; ++p) { unsigned int prime = primes[p]; mpz_set_ui(tmp2, prime); mpz_powm_ui(tmp, num, (prime-1)/2, tmp2); if(mpz_cmp_ui(tmp, 1)) // Skip non-quadratic residues continue; used_primes[next_prime] = prime; used_log[next_prime] = log_primes[p]; // Generate more exact candidates for(int i = next_cand; i < prime; ++i) { mpz_set_ui(tmp, root + i); mpz_pow_ui(tmp, tmp, 2); mpz_sub(tmp, tmp, num); mpz_set(first_cands[i], tmp); } next_cand = prime; // find offsets for them // TODO Shanks-tonelli unsigned int foo = tonelli_shanks(num, prime); printf("root for %u is %u and %u\n", prime, foo, prime-foo); size_t idx = 0; for(int i = 0; i < prime; ++i) { if(mpz_divisible_ui_p(first_cands[i], prime)) { offsets[next_prime][idx++] = i; if(idx == 2) break; } } assert(idx == 2); ++next_prime; } // sieve until we find more than B candidates, guarantees linear dependence size_t sieve_offset = 0; while(num_cands <= B) { for(size_t i = 0; i < sieve_size; ++i) { double d = root + i; d += sieve_offset; table[i] = log(d*d-approx); } // cross out even ones for(size_t i = mpz_tstbit(tmp, 1)^(sieve_offset & 1); i < sieve_size; i+=2) table[i] -= log_primes[0]; for(int p = 1; p < next_prime && num_cands <= B; ++p) { unsigned int prime = used_primes[p]; double log_prime = used_log[p]; // fprintf(stderr, "offsets[%d] are %d and %d\n", used_primes[p], offsets[p][0], offsets[p][1]); for(int x = 0; x < 2; ++x) { size_t off = (offsets[p][x] + sieve_offset + prime-1) % prime; for(int a = off; a < sieve_size; a += prime) { table[a] -= log_prime; if(table[a] > LIMIT) continue; cand_offsets[num_cands++] = root + a + sieve_offset; if(num_cands > B) break; } } } sieve_offset += sieve_size; } for(size_t i = 0; i < num_cands; ++i) { //fprintf(stderr, "%llu\n", cand_offsets[i]); // TODO REMOVE VERY SLOW STUFF mpz_set_ui(tmp, root + i); mpz_pow_ui(tmp, tmp, 2); mpz_sub(tmp, tmp, num); // mpz_out_str(stderr, 10, tmp); // fputc('\n', stderr); } fprintf(stderr, "%d used candidates\n", num_cands); free(table); mpz_clear(tmp); mpz_clear(tmp2); }
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 ovm_q_pow(oregister_t *l, oregister_t *r) { switch (r->t) { case t_void: if (!cfg_float_format) { l->t = t_float; l->v.d = 1.0; } else { l->t = t_mpr; mpfr_set_ui(orr(l), 1, thr_rnd); } break; case t_word: if (!cfg_float_format) { l->t = t_float; l->v.d = pow(mpq_get_d(oqr(l)), r->v.w); } else { mpfr_set_si(orr(r), r->v.w, thr_rnd); goto mpr; } break; case t_float: if (mpq_sgn(oqr(l)) < 0 && finite(r->v.d) && rint(r->v.d) != r->v.d) { real(r->v.dd) = r->v.d; imag(r->v.dd) = 0.0; goto cdd; } l->t = t_float; l->v.d = pow(mpq_get_d(oqr(l)), r->v.d); break; case t_mpz: if (!cfg_float_format) { l->t = t_float; l->v.d = pow(mpq_get_d(oqr(l)), mpz_get_d(ozr(r))); } else { mpfr_set_z(orr(r), ozr(r), thr_rnd); goto mpr; } break; case t_rat: if (mpq_sgn(oqr(l)) < 0) { if (!cfg_float_format) { real(r->v.dd) = mpq_get_d(oqr(r)); imag(r->v.dd) = 0.0; goto cdd; } mpc_set_q(occ(r), oqr(r), thr_rndc); goto mpc; } else { if (!cfg_float_format) { l->t = t_float; l->v.d = pow(mpq_get_d(oqr(l)), rat_get_d(r->v.r)); } else { mpq_set_si(oqr(r), rat_num(r->v.r), rat_den(r->v.r)); mpfr_set_q(orr(r), oqr(r), thr_rnd); goto mpr; } } break; case t_mpq: if (mpq_sgn(oqr(r)) < 0) { if (!cfg_float_format) { real(r->v.dd) = mpq_get_d(oqr(r)); imag(r->v.dd) = 0.0; goto cdd; } mpc_set_q(occ(r), oqr(r), thr_rndc); goto mpc; } else { if (!cfg_float_format) { l->t = t_float; l->v.d = pow(mpq_get_d(oqr(l)), mpq_get_d(oqr(r))); } else { mpfr_set_q(orr(r), oqr(r), thr_rnd); goto mpr; } } break; case t_mpr: if (mpq_sgn(oqr(l)) < 0 && mpfr_number_p(orr(r)) && !mpfr_integer_p(orr(r))) { mpc_set_q(occ(r), oqr(r), thr_rndc); goto mpc; } mpr: l->t = t_mpr; mpfr_set_q(orr(l), oqr(l), thr_rnd); mpfr_pow(orr(l), orr(l), orr(r), thr_rnd); break; case t_cdd: cdd: l->t = t_cdd; real(l->v.dd) = mpq_get_d(oqr(l)); imag(l->v.dd) = 0.0; l->v.dd = cpow(l->v.dd, r->v.dd); check_cdd(l); break; case t_cqq: if (!cfg_float_format) { real(r->v.dd) = mpq_get_d(oqr(r)); imag(r->v.dd) = mpq_get_d(oqi(r)); goto cdd; } mpc_set_q_q(occ(r), oqr(r), oqi(r), thr_rndc); case t_mpc: mpc: l->t = t_mpc; mpc_set_q(occ(l), oqr(l), thr_rndc); mpc_pow(occ(l), occ(l), occ(r), thr_rndc); check_mpc(l); break; default: ovm_raise(except_not_a_number); } }
void bern_rat(mpq_t res, long k, int num_threads) { // special cases if (k == 0) { // B_0 = 1 mpq_set_ui(res, 1, 1); return; } if (k == 1) { // B_1 = -1/2 mpq_set_si(res, -1, 2); return; } if (k == 2) { // B_2 = 1/6 mpq_set_si(res, 1, 6); return; } if (k & 1) { // B_k = 0 if k is odd mpq_set_ui(res, 0, 1); return; } if (num_threads <= 0) num_threads = 1; mpz_t num, den; mpz_init(num); mpz_init(den); const double log2 = 0.69314718055994528622676; const double invlog2 = 1.44269504088896340735992; // = 1/log(2) // compute preliminary prime bound and build prime table long bound1 = (long) max(37.0, ceil((k + 0.5) * log(k) * invlog2)); PrimeTable table(bound1); // compute denominator of B_k bern_den(den, k, table); // compute number of bits we need to resolve the numerator long bits = (long) ceil((k + 0.5) * log(k) * invlog2 - 4.094 * k + 2.470 + log(mpz_get_d(den)) * invlog2); // compute tighter prime bound // (note: we can safely get away with double-precision here. It would // only start being insufficient around k = 10^13 or so, which is totally // impractical at present.) double prod = 1.0; long prod_bits = 0; long p; for (p = 5; prod_bits < bits + 1; p = table.next_prime(p)) { if (p >= NTL_SP_BOUND) abort(); // !!!!! not sure what else we can do here... if (k % (p-1) != 0) prod *= (double) p; int exp; prod = frexp(prod, &exp); prod_bits += exp; } long bound2 = p; State state(k, bound2, table); #ifdef USE_THREADS vector<pthread_t> threads(num_threads - 1); pthread_attr_t attr; pthread_attr_init(&attr); #ifdef THREAD_STACK_SIZE pthread_attr_setstacksize(&attr, THREAD_STACK_SIZE * 1024); #endif // spawn worker threads to process blocks for (long i = 0; i < num_threads - 1; i++) pthread_create(&threads[i], &attr, worker, &state); #endif worker(&state); // make this thread a worker too #ifdef USE_THREADS for (long i = 0; i < num_threads - 1; i++) pthread_join(threads[i], NULL); #endif pthread_attr_destroy (&attr); // reconstruct B_k as a rational number Item* item = *(state.items.begin()); mpz_mul(num, item->residue, den); mpz_mod(num, num, item->modulus); if (k % 4 == 0) { // B_k is negative mpz_sub(num, item->modulus, num); mpz_neg(num, num); } delete item; mpz_swap(num, mpq_numref(res)); mpz_swap(den, mpq_denref(res)); mpz_clear(num); mpz_clear(den); }
void ovm_q_hypot(oregister_t *l, oregister_t *r) { switch (r->t) { case t_void: if (!cfg_float_format) { l->t = t_float; l->v.d = fabs(mpq_get_d(oqr(l))); } else { mpfr_set_ui(orr(r), 0, thr_rnd); goto mpr; } break; case t_word: if (!cfg_float_format) { l->t = t_float; l->v.d = hypot(mpq_get_d(oqr(l)), r->v.w); } else { mpfr_set_si(orr(r), r->v.w, thr_rnd); goto mpr; } break; case t_float: l->t = t_float; l->v.d = hypot(mpq_get_d(oqr(l)), r->v.d); break; case t_mpz: if (!cfg_float_format) { l->t = t_float; l->v.d = hypot(mpq_get_d(oqr(l)), mpz_get_d(ozr(r))); } else { mpfr_set_z(orr(r), ozr(r), thr_rnd); goto mpr; } break; case t_rat: if (!cfg_float_format) { l->t = t_float; l->v.d = hypot(mpq_get_d(oqr(l)), rat_get_d(r->v.r)); } else { mpq_set_si(oqr(r), rat_num(r->v.r), rat_den(r->v.r)); mpfr_set_q(orr(r), oqr(r), thr_rnd); goto mpr; } break; case t_mpq: if (!cfg_float_format) { l->t = t_float; l->v.d = hypot(mpq_get_d(oqr(l)), mpq_get_d(oqr(r))); } else { mpfr_set_q(orr(r), oqr(r), thr_rnd); goto mpr; } break; case t_mpr: mpr: l->t = t_mpr; mpfr_set_q(orr(l), oqr(l), thr_rnd); mpfr_hypot(orr(l), orr(l), orr(r), thr_rnd); break; case t_cdd: cdd: l->t = t_float; l->v.d = hypot(mpq_get_d(oqr(l)), hypot(real(r->v.dd), imag(r->v.dd))); break; case t_cqq: if (!cfg_float_format) { real(r->v.dd) = mpq_get_d(oqr(r)); imag(r->v.dd) = mpq_get_d(oqi(r)); goto cdd; } mpc_set_q_q(occ(r), oqr(r), oqi(r), thr_rndc); case t_mpc: l->t = t_mpr; mpc_set_q(occ(l), oqr(l), thr_rndc); mpfr_hypot(ori(l), orr(l), ori(l), thr_rnd); mpfr_hypot(orr(l), orr(r), ori(r), thr_rnd); mpfr_hypot(orr(l), ori(l), orr(l), thr_rnd); break; default: ovm_raise(except_not_a_number); } }
explicit operator double() const { return mpz_get_d(m_data); }
inline void incrementTime(unsigned int step = 1) { for (unsigned int i = 0; i < step; i++) mpz_add(_timeOfEvent, _timeOfEvent, _tickIncrement); _dTime = mpz_get_d(_timeOfEvent)*_tick; }