GmpInt& GmpInt::operator/=(long value) { copyIfShared(); if(value >= 0) mpz_tdiv_q_ui(mData->mInteger, mData->mInteger, value); else { mpz_neg(mData->mInteger, mData->mInteger); mpz_tdiv_q_ui(mData->mInteger, mData->mInteger, -value); } return *this; }
void mpz_arctan(mpz_t r, unsigned long base, mpz_t pow, mpz_t t1, mpz_t t2) { unsigned long i = 1; mpz_tdiv_q_ui(r, pow, base); mpz_set(t1, r); do { mpz_ui_pow_ui(t2, base, 2); mpz_tdiv_q(t1, t1, t2); mpz_tdiv_q_ui(t2, t1, 2*i+1); if (i++ & 1) mpz_sub(r, r, t2); else mpz_add(r, r, t2); } while (mpz_sgn(t2)); }
void main() { char* hex = "49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d"; mpz_t decimal; mpz_init(decimal); int exponent = 0; for (int i = strlen(hex)-1; i >= 0; i--) { int number = hex2decimal(hex[i]); // decimal += number * (int)Math.pow(16, exponent); mpz_t power; // mpz_t must be initialized before mpz_ui_pow_ui() mpz_init(power); mpz_ui_pow_ui(power, 16, exponent); mpz_addmul_ui(decimal, power, number); // printf("hex: %c, number: %d, exponent: %d, decimal: ", hex[i], number, exponent); // mpz_out_str(stdout, 10, decimal); // printf("\n"); exponent += 1; } char* builder = malloc(sizeof(strlen(hex))); int divider = 64; mpz_t number; mpz_init_set(number, decimal); int index = 0; while (mpz_cmp_ui(number, divider) > 0) { mpz_t quotient; int remainder = mpz_tdiv_q_ui(quotient, number, divider); char letter = decimal2base64(remainder); builder[index] = letter; index++; mpz_set(number, quotient); } mpz_t quotient; int remainder = mpz_tdiv_q_ui(quotient, number, divider); char letter = decimal2base64(remainder); builder[index] = letter; index++; builder[index] = '\0'; char* result = malloc(sizeof(strlen(builder)+1)); strcpy(result, builder); reverse(result); puts(result); char* base64 = "SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t"; printf("hex: %s\n", hex); printf("decimal: "); mpz_out_str(stdout, 10, decimal); printf("\n"); printf("base64: %s\n", base64); printf(strcmp(result, base64) == 0 ? "passed\n" : "failed\n"); }
void actan(mpz_t res, unsigned long base, mpz_t pows) { int i, neg = 1; mpz_tdiv_q_ui(res, pows, base); mpz_set(tmp1, res); for (i = 3; ; i += 2) { mpz_tdiv_q_ui(tmp1, tmp1, base * base); mpz_tdiv_q_ui(tmp2, tmp1, i); if (mpz_cmp_ui(tmp2, 0) == 0) break; if (neg) mpz_sub(res, res, tmp2); else mpz_add(res, res, tmp2); neg = !neg; } }
char * mpc_get_str (mpc_t op) { char *return_value; mpz_t temp_op; mpz_t temp1; mpz_t temp2; if (op.precision == 0) return_value = mpz_get_str (NULL, 10, op.object); else { mpz_init (temp_op); mpz_abs (temp_op, op.object); mpz_init_set (temp1, temp_op); mpz_init_set_ui (temp2, 1); power_of_ten (temp2, op.precision); mpz_tdiv_q (temp1, temp1, temp2); return_value = concatinate_free (mpz_get_str (NULL, 10, temp1), ".", true, false); mpz_mul (temp1, temp1, temp2); mpz_sub (temp1, temp_op, temp1); mpz_abs (temp1, temp1); mpz_tdiv_q_ui (temp2, temp2, 10); while (mpz_cmp (temp2, temp1) > 0) { return_value = concatinate_free (return_value, "0", true, false); mpz_tdiv_q_ui (temp2, temp2, 10); } return_value = concatinate_free (return_value, mpz_get_str (NULL, 10, temp1), true, true); if (mpz_sgn (op.object) < 0) return_value = concatinate_free ("-", return_value, false, true); mpz_clear (temp1); mpz_clear (temp2); mpz_clear (temp_op); } return return_value; }
void mpc_get_mpz (mpz_t rop, mpc_t op) { mpz_set (rop, op.object); while (op.precision-- != 0) mpz_tdiv_q_ui (rop, rop, 10); }
void fmpz_tdiv_q_ui(fmpz_t f, const fmpz_t g, ulong h) { fmpz c1 = *g; ulong c2 = h; if (h == 0) { printf("Exception: division by zero in fmpz_tdiv_q_ui\n"); abort(); } if (!COEFF_IS_MPZ(c1)) /* g is small */ { if (c1 > 0) { fmpz_set_ui(f, c1 / c2); } else { ulong q = ((ulong) -c1) / c2; fmpz_set_si(f, - (long) q); } } else /* g is large */ { __mpz_struct *mpz_ptr = _fmpz_promote(f); mpz_tdiv_q_ui(mpz_ptr, COEFF_TO_PTR(c1), c2); _fmpz_demote_val(f); /* division by h may result in small value */ } }
void factor(mpz_t num) { if(mpz_probab_prime_p(num, 10) > 0) { mpz_set(factors[num_factors++], num); return; } // Trial division, "fairly cheap" compared to rest of QS for(size_t i = 0; i < num_primes; ++i) { while(mpz_tdiv_q_ui(q, num, primes[i]) == 0) { mpz_set_ui(factors[num_factors++], primes[i]); mpz_set(num, q); } } if(!mpz_cmp_ui(num, 1)) // If num==1 we're done return; if(mpz_probab_prime_p(num, 10) > 0) { mpz_set(factors[num_factors++], num); return; } sieve_factor(num); }
/* First version -- uses Taylor series for exp(x) directly, broken into two pieces Note: this version is currently not used in the benchmark below */ void fix_exp(mpz_t z, mpz_t x, int prec) { int k; int r = 8; //prec += 20; //mpz_set(_exp_x, x); //mpz_tdiv_q_2exp(_exp_x, _exp_x, r); mpz_tdiv_q_2exp(_exp_x, x, r); mpz_set_ui(_exp_s0, 1); mpz_mul_2exp(_exp_s0, _exp_s0, prec); mpz_set(_exp_s1, _exp_s0); mpz_mul(_exp_x2, _exp_x, _exp_x); mpz_tdiv_q_2exp(_exp_x2,_exp_x2,prec); mpz_set(_exp_a, _exp_x2); k = 2; while(1) { mpz_tdiv_q_ui(_exp_a, _exp_a, k); if (mpz_sgn(_exp_a) == 0) break; mpz_add(_exp_s0, _exp_s0, _exp_a); k += 1; mpz_tdiv_q_ui(_exp_a, _exp_a, k); if (mpz_sgn(_exp_a) == 0) break; mpz_add(_exp_s1, _exp_s1, _exp_a); k += 1; mpz_mul(_exp_a, _exp_a, _exp_x2); mpz_tdiv_q_2exp(_exp_a,_exp_a,prec); if (mpz_sgn(_exp_a) == 0) break; } mpz_mul(_exp_s1, _exp_s1, _exp_x); mpz_tdiv_q_2exp(_exp_s1,_exp_s1,prec); mpz_add(_exp_s0, _exp_s0, _exp_s1); for(k=0; k<r; k++) { mpz_mul(_exp_s0, _exp_s0, _exp_s0); mpz_tdiv_q_2exp(_exp_s0,_exp_s0,prec); } //mpz_tdiv_q_ui(z, _exp_s0, 20); mpz_set(z, _exp_s0); }
/** * @brief Check if an node is a white move * @param[in] id The identifier used * @return 1 If the node is a white move * @return 0 Otherwise * * This function check if a given node is a white move * or not, given its Identifier * */ int identifier_is_white(Identifier id) { Identifier tmp; int ret; mpz_init(tmp); mpz_tdiv_q_ui(tmp, id, 100000); ret = (mpz_tdiv_ui(tmp, 10) % 2); mpz_clear(tmp); return ret; }
/** * @brief Check if an node contains a enpassant move * @param[in] id The identifier used * @return 1 If the node contains enpassant * @return 0 Otherwise * * This function check if a given node contains a enpassant move * or not, given its Identifier * */ int identifier_is_passant(Identifier id) { Identifier tmp; int ret; mpz_init(tmp); mpz_tdiv_q_ui(tmp, id, 10000); ret = mpz_tdiv_ui(tmp, 10); mpz_clear(tmp); return ret; }
/** * @brief Get the castling state * @param[in] id The identifier used * @return [|0;15|] Meaning a state of castling * * This function check the castling state of an node, given its * Identifier * */ int identifier_get_cast(Identifier id) { Identifier tmp; int ret; mpz_init(tmp); mpz_tdiv_q_ui(tmp, id, 100); ret = mpz_tdiv_ui(tmp, 100); mpz_clear(tmp); return ret; }
void bg_decrypt_block(bg_prikey key, FILE *in, FILE *out, mp_size_t len) { mpz_t y, xqmp, xpmq, pp, qq, negone; unsigned long int l; bbs_state *bbs; mpz_init(y); mpz_init(xqmp); mpz_init(xpmq); mpz_init(pp); mpz_init(qq); mpz_init_set_si(negone, -1); bbs = init_bbs(negone, key.n); bbs_gen(bbs, NULL, 8*len, 0); bbs_iter(bbs); bbs_close(bbs); l = bbs->len; mpz_inp_raw(y, in); mpz_add_ui(pp, key.p, 1); mpz_tdiv_q_ui(pp, pp, 4); mpz_pow_ui(pp, pp, l); mpz_powm_sec(pp, y, pp, key.p); mpz_add_ui(qq, key.q, 1); mpz_tdiv_q_ui(qq, qq, 4); mpz_pow_ui(qq, qq, l); mpz_powm_sec(qq, y, qq, key.q); mpz_mul(xqmp, key.q, pp); mpz_powm(pp, key.q, negone, key.p); mpz_mul(xqmp, xqmp, pp); mpz_mul(xpmq, key.p, qq); mpz_powm(qq, key.p, negone, key.q); mpz_mul(xpmq, xpmq, qq); mpz_add(y, xqmp, xpmq); mpz_mod(y, y, key.n); bbs = init_bbs(y, key.n); while(len && !feof(in)) len -= bg_xor(bbs, in, out, len); bbs_close(bbs); }
mpz_class digitalSum( mpz_class x ) { mpz_class result = 0; unsigned long digit; while( x != 0 ) { digit = mpz_tdiv_q_ui( x.get_mpz_t(), x.get_mpz_t(), 10 ); result += digit; } return result; }
void S1(mpz_t n, uint64_t crn, int8_t* mu, mpz_t result) { mpz_t tmp; mpz_inits(result, tmp, NULL); uint64_t i; for(i=1; i<=crn; i++) { mpz_tdiv_q_ui(tmp, n, i); mpz_mul_si(tmp, tmp, mu[i]); mpz_add(result, result, tmp); } }
/** * @brief Extract an item from the stack * @return -1 If the stack is empty * @return int the first element of the stack * * This function extract an item from the stack * and returns it * @note If the stack contains 0 it means it is empty since * the moveGenerator will never add the a1a1 move. * */ int stack_pop(Stack *s) { mpz_t tmp; int ret; if (!mpz_cmp_ui(*s, 0)) { ret = -1; } else { mpz_init_set(tmp, *s); ret = (mpz_tdiv_q_ui(*s, tmp, MAX_PAIRS)); mpz_clear(tmp); } return ret; }
unsigned int isTruncatableRight(mpz_t n) { mpz_t value; mpz_init(value); mpz_set(value, n); while (mpz_cmp_ui(value, 0) > 0) { //printNumber("right ", value, "\n"); if (!isPrime(value)) return 0; mpz_tdiv_q_ui(value, value, 10); } return 1; }
static void select_curve_params(mpz_t a, mpz_t b, mpz_t g, long D, mpz_t *roots, long i, mpz_t N, mpz_t t) { int N_is_not_1_congruent_3; mpz_set_ui(a, 0); mpz_set_ui(b, 0); if (D == -3) { mpz_set_si(b, -1); } else if (D == -4) { mpz_set_si(a, -1); } else { mpz_sub_ui(t, roots[i], 1728); mpz_mod(t, t, N); /* c = (j * inverse(j-1728)) mod n */ if (mpz_divmod(b, roots[i], t, N, b)) { mpz_mul_si(a, b, -3); /* r = -3c */ mpz_mul_si(b, b, 2); /* s = 2c */ } } mpz_mod(a, a, N); mpz_mod(b, b, N); /* g: 1 < g < Ni && (g/Ni) != -1 && (g%3!=1 || cubic non-residue) */ N_is_not_1_congruent_3 = ! mpz_congruent_ui_p(N, 1, 3); for ( mpz_set_ui(g, 2); mpz_cmp(g, N) < 0; mpz_add_ui(g, g, 1) ) { if (mpz_jacobi(g, N) != -1) continue; if (N_is_not_1_congruent_3) break; mpz_sub_ui(t, N, 1); mpz_tdiv_q_ui(t, t, 3); mpz_powm(t, g, t, N); /* t = g^((Ni-1)/3) mod Ni */ if (mpz_cmp_ui(t, 1) == 0) continue; if (D == -3) { mpz_powm_ui(t, t, 3, N); if (mpz_cmp_ui(t, 1) != 0) /* Additional check when D == -3 */ continue; } break; } if (mpz_cmp(g, N) >= 0) /* No g can be found: N is composite */ mpz_set_ui(g, 0); }
char factored(long lptr,mpz_t T) { char facted = FALSE;// 可以分解 int i,j,r,st; partial = FALSE;// 被分成了两个部分 for(j=1;j<=mm;j++) // 尝试完全分解它 { r=(int)(lptr%epr[j]); if(r<0) r+=epr[j]; if(r!=r1[j] && r!=r2[j]) continue; while(mpz_tdiv_q_ui(X, T, epr[j])==0) // X = T/epr[j],尝试对 T 用 epr[j] 做质因数分解 { e[j]++;// 指数+1 if(X!=T) mpz_set(T, X); //T = X,继续做 } st=qsieve_getsize(T); // 如果T fits in int那么 st 存的就是 T if(st==1) // 被当前的epr[j]分解成1了,直接返回true { facted=TRUE; break; } if(qsieve_getsize(X)<=epr[j]) // X保存的是最后一次 T/epr[j] 的结果,尽管epr[j]可能不整除 T { if(st>=0x7FFFFFFF || (st/epr[mm])>(1+mlf/50)) break; if(st<=epr[mm]) // 当前剩下的数比epr中最大的那个要小,那么就找找看后面的素数 for(i=j;i<=mm;i++) if(st==epr[i]) { e[i]++; facted=TRUE; break; } if(facted) break; //没有被部分分解,partial=false lp=st; partial=TRUE; //被部分分解了 facted=TRUE; break; } } return facted; }
unsigned int isTruncatableLeft(mpz_t n) { unsigned int len = numberLength(n); mpz_t value, power; mpz_init(value); mpz_init(power); mpz_set(value, n); mpz_set_ui(power, 1); for (unsigned int i = 1; i < len; i++) mpz_mul_ui(power, power, 10); while (mpz_cmp_ui(power, 0) > 0) { //printNumber("left ", value, ", power "); //printNumber("", power, "\n"); if (!isPrime(value)) return 0; mpz_mod(value, value, power); mpz_tdiv_q_ui(power, power, 10); } return 1; }
/** * @brief Puts the "history" part of id in a stack * @param[in] id The identifier holding the data * @param[out] stack The stack in which to store extracted data * * Extract the "history" part of the identifier (the moves since root board) * and store it in a stack * */ int identifier_to_stack(Identifier id, Stack *stack) { return mpz_tdiv_q_ui(*stack, id, 1000000); }
int main() { unsigned int i,j,a,*SV; unsigned char logpi; int k,S,r,s1,s2,s,NS,logm,ptr,threshold,epri; long M,la,lptr; qsieve=gmpinit(-36,0); if(initv()<0) return 0; hmod=2*mlf+1; mpz_set_si(TA, hmod); while(!mpz_probab_prime_p(TA, qsieve->NTRY)) mpz_sub_ui(TA, TA, 2); //TT=不大于TT的素数 hmod=qsieve_getsize(TA); hmod2=hmod-2; for(k=0;k<hmod;k++) hash[k]=(-1); M=50*(long)mm; NS=(int)(M/SSIZE); if(M%SSIZE!=0) NS++; M=SSIZE*(long)NS; // M为不小于50*mm的SSIZE的倍数中最小的 from 以上四行 logm=0; la=M; while((la/=2)>0) logm++; // 以2为底 rp[0]=logp[0]=0; for(k=1;k<=mm;k++) //求k*N在每个素数下的二次剩余解,与每个素数的ln(pi) { r=mpz_tdiv_q_ui(TA, D, epr[k]); rp[k]=qsieve_sqrmp(r,epr[k]); logp[k]=0; r=epr[k]; while((r/=2)>0) logp[k]++; } r=mpz_tdiv_q_ui(TA, D, 8); if(r==5) logp[1]++; if(r==1) logp[1]+=2; threshold=logm+mpz_sizeinbase(R, 2)-2*logp[mm]; jj=0; nlp=0; mpz_mul_si(DG, D, 2); mpz_root(DG, DG, 2); mpz_set_si(TA, M); qsieve_divide(DG,TA,DG); mpz_root(DG, DG, 2); if(mpz_tdiv_q_ui(TA, DG, 2)==0) mpz_add_ui(DG, DG, 1); if(mpz_tdiv_q_ui(TA, DG, 4)==1) mpz_add_ui(DG, DG, 2); // 令DG等于大于等于DG的数中模4余3的最小的数 printf(" 0%"); while(1) //不断尝试新的多项式,可以并行计算 { r=qsieve->NTRY; qsieve->NTRY=1; do { do { mpz_add_ui(DG, DG, 4); } while(!(mpz_probab_prime_p(DG, qsieve->NTRY) ? TRUE : FALSE)); mpz_sub_ui(TA, DG, 1); mpz_tdiv_q_ui(TA, TA, 2); mpz_powm_sec(TA, D, TA, DG); } while(qsieve_getsize(TA)!=1); //直到DD是二次剩余 qsieve->NTRY=r; mpz_add_ui(TA, DG, 1); mpz_tdiv_q_ui(TA, TA, 4); mpz_powm_sec(B, D, TA, DG); mpz_neg(TA, D); qsieve_muladddiv(B,B,TA,DG,TA,TA); mpz_neg(TA, TA); mpz_mul_si(A, B, 2); qsieve_extgcd(A,DG,A,A,A); qsieve_muladddiv(A,TA,TA,DG,DG,A); mpz_mul(TA, A, DG); mpz_add(B, B, TA); mpz_mul(A, DG, DG); qsieve_extgcd(DG,D,IG,IG,IG); r1[0]=r2[0]=0; for(k=1;k<=mm;k++) //s1和s2是两个解 { s=mpz_tdiv_q_ui(TA, B, epr[k]); r=mpz_tdiv_q_ui(TA, A, epr[k]); r=qsieve_getinvers(r,epr[k]); s1=(epr[k]-s+rp[k]); s2=(epr[k]-s+epr[k]-rp[k]); if(s1 > s2) { int t = s1; s1 = s2; s2 = t; } r1[k]=(int)((((long long)s1)*((long long)r)) % ((long long)epr[k])); r2[k]=(int)((((long long)s2)*((long long)r)) % ((long long)epr[k])); } for(ptr=(-NS);ptr<NS;ptr++) { la=(long)ptr*SSIZE; SV=(unsigned int *)sieve; for(i=0; i<SSIZE/sizeof(int); i++) *SV++=0; for(k=1; k<=mm; k++) { epri=epr[k]; logpi=logp[k]; r=(int)(la%epri); s1=(r1[k]-r)%epri; if(s1<0) s1+=epri; s2=(r2[k]-r)%epri; if(s2<0) s2+=epri; /* 这部分是筛法的主要部分,数组下标表示多项式P(x)的参数x s1与s2是两个P(x)=0(mod p)的解 */ for(j=s1;j<SSIZE;j+=epri) sieve[j]+=logpi; if(s1==s2) continue; for(j=s2;j<SSIZE;j+=epri) sieve[j]+=logpi; } for(a=0;a<SSIZE;a++) //找那些没有被筛掉的数 { if(sieve[a]<threshold) continue; lptr=la+a; mpz_set_si(TA, lptr); S=0; mpz_mul(TA, A, TA); mpz_add(TA, TA, B); qsieve_muladddiv(TA,IG,TA,D,D,P); if(qsieve_getsize(P)<0) mpz_add(P, P, D); qsieve_muladddiv(P,P,P,D,D,V); mpz_abs(TA, TA); if(qsieve_compare(TA,R)<0) S=1; if(S==1) mpz_sub(V, D, V); if(V!=TA) mpz_set(TA, V); e[0]=S; for(k=1;k<=mm;k++) e[k]=0; if(!factored(lptr,TA)) continue; if(gotcha()) { mpz_gcd(P, TA, N); qsieve_getsize(P); printf("\b\b\b\b100%\nFactors are\n"); qsieve_outnum(P,stdout); qsieve_divide(N,P,N); qsieve_outnum(N,stdout); return 0; } } } } return 0; }
/* Computes the exponential / trigonometric series alt = 0 -- c = cosh(x), s = sinh(x) alt = 1 -- c = cos(x), s = sin(x) alt = 2 -- c = exp(x), s = n/a using the cosh/sinh series. Parameters: prec -- r -- number of argument reductions J -- number of partitions of the series */ void exp_series(mpz_t c, mpz_t s, mpz_t x, int prec, int r, int J, int alt) { int i, k, wp; wp = prec + 2*r + 10; mpz_fixed_one(_exp_one, wp); /* x / 2^r, adjusted to wp */ mpz_mul_2exp(_exp_x, x, wp-prec); mpz_tdiv_q_2exp(_exp_x, _exp_x, r); if (J < 1) J = 1; for (i=0; i<J; i++) { if (i == 0) { mpz_set(_exp_pows[i], _exp_one); } else if (i == 1) { mpz_mul(_exp_pows[i], _exp_x, _exp_x); mpz_tdiv_q_2exp(_exp_pows[i], _exp_pows[i], wp); } else { mpz_mul(_exp_pows[i], _exp_pows[i-1], _exp_pows[1]); mpz_tdiv_q_2exp(_exp_pows[i], _exp_pows[i], wp); } mpz_set_ui(_exp_sums[i], 0); } if (J == 1) { mpz_mul(_exp_x, _exp_x, _exp_x); mpz_tdiv_q_2exp(_exp_x, _exp_x, wp); mpz_set(_exp_a, _exp_x); } else { mpz_mul(_exp_x, _exp_pows[J-1], _exp_pows[1]); mpz_tdiv_q_2exp(_exp_x, _exp_x, wp); mpz_set(_exp_a, _exp_pows[1]); } k = 2; while (mpz_sgn(_exp_a) != 0) { for (i=0; i<J; i++) { mpz_tdiv_q_ui(_exp_a, _exp_a, (k-1)*k); if ((alt == 1) && (k & 2)) { mpz_sub(_exp_sums[i], _exp_sums[i], _exp_a); } else { mpz_add(_exp_sums[i], _exp_sums[i], _exp_a); } k += 2; } mpz_mul(_exp_a, _exp_a, _exp_x); mpz_tdiv_q_2exp(_exp_a, _exp_a, wp); } for (i=1; i<J; i++) { mpz_mul(_exp_sums[i], _exp_sums[i], _exp_pows[i]); mpz_tdiv_q_2exp(_exp_sums[i], _exp_sums[i], wp); } mpz_set(c, _exp_one); for (i=0; i<J; i++) { mpz_add(c, c, _exp_sums[i]); } /* Repeatedly apply the duplication formula cosh(2*x) = 2*cosh(x)^2 - 1 cos(2*x) = 2*cos(x)^2 - 1 exp(2*x) = exp(x)^2 */ if (alt == 2) { /* s = sqrt(|1-c^2|) */ mpz_mul_2exp(_exp_one, _exp_one, wp); mpz_mul(s, c, c); mpz_sub(s, _exp_one, s); mpz_abs(s, s); mpz_sqrt(s, s); mpz_add(c, c, s); for (i=0; i<r; i++) { mpz_mul(c, c, c); mpz_tdiv_q_2exp(c, c, wp); } } else { for (i=0; i<r; i++) { mpz_mul(c, c, c); mpz_tdiv_q_2exp(c, c, wp-1); mpz_sub(c, c, _exp_one); } /* s = sqrt(|1-c^2|) */ mpz_mul_2exp(_exp_one, _exp_one, wp); mpz_mul(s, c, c); mpz_sub(s, _exp_one, s); mpz_abs(s, s); mpz_sqrt(s, s); } mpz_tdiv_q_2exp(c, c, wp-prec); mpz_tdiv_q_2exp(s, s, wp-prec); }
int perform_xSigmax(struct classify_data* data) { //printf("Going to start x'Sigmax calculation\n"); void* socket = data->socket; paillier_pubkey_t* pkey = data->pub; paillier_prvkey_t* skey = data->prv; mpz_t mid; mpz_init_set(mid,pkey->n); mpz_tdiv_q_ui(mid,mid,2); paillier_plaintext_t** texts = data->texts; int len = data->maxcol; int i,j; int nlen; paillier_ciphertext_t** z = perform_sip(socket,pkey,texts,len,&nlen,data->rand); paillier_plaintext_t** ai = (paillier_plaintext_t**)malloc(nlen*sizeof(paillier_plaintext_t*)); //TODO: find out why I can't use free_cipherarray here? for(j=0;j<nlen;j++){ ai[j] = paillier_dec(NULL,pkey,skey,z[j]); if(mpz_cmp(ai[j]->m,mid)>0){ mpz_sub(ai[j]->m,ai[j]->m,pkey->n); } paillier_freeciphertext(z[j]); } free(z); //printf("Recieved the result of x'Sigma for all sigmas\n"); z = perform_sip(socket,pkey,texts,len,&nlen,data->rand); paillier_plaintext_t** qi = (paillier_plaintext_t**)malloc(nlen*sizeof(paillier_plaintext_t*)); for(j=0;j<nlen;j++){ qi[j] = paillier_dec(NULL,pkey,skey,z[j]); if(mpz_cmp(qi[j]->m,mid)>0){ mpz_sub(qi[j]->m,qi[j]->m,pkey->n); } } free_cipherarray(z,nlen); //printf("Recieved the result of bx\n"); mpz_t* aix = (mpz_t*)malloc(len*sizeof(mpz_t)); mpz_t tmp; for(i=0;i<nlen;i++){ mpz_init(aix[i]); mpz_add(aix[i],aix[i],qi[i]->m); } mpz_init(tmp); for(i=0;i<data->maxcol;i++){ for(j=0;j<nlen;j++){ mpz_mul(tmp,ai[j*data->maxcol+i]->m,texts[i]->m); mpz_add(aix[j],aix[j],tmp); } } //printf("Computed new answers\n"); int index=0; mpz_t maxval; mpz_init(maxval); mpz_set(maxval,aix[0]); for(i=0;i<nlen;i++){ // mpz_tdiv_q_ui(aix[i],aix[i],1000*1000*1000); // gmp_printf("ANSWER: %Zd\n",aix[i]); if(mpz_cmp(aix[i],maxval) > 0){ index = i; mpz_set(maxval,aix[i]); } mpz_clear(aix[i]); paillier_freeplaintext(ai[i]); paillier_freeplaintext(qi[i]); } // gmp_printf("Max index was: %i with value %Zd\n",index,maxval); mpz_clear(maxval); free(aix); mpz_clear(tmp); //TODO: ask keith why this doesn't work //free(ai); return index; }
void zTrial(fact_obj_t *fobj) { //trial divide n using primes below limit. optionally, print factors found. //input expected in the gmp_n field of div_obj. uint32 r,k=0; uint32 limit = fobj->div_obj.limit; int print = fobj->div_obj.print; FILE *flog; fp_digit q; mpz_t tmp; mpz_init(tmp); flog = fopen(fobj->flogname,"a"); if (flog == NULL) { printf("fopen error: %s\n", strerror(errno)); printf("could not open %s for writing\n",fobj->flogname); return; } if (P_MAX < limit) { free(PRIMES); PRIMES = soe_wrapper(spSOEprimes, szSOEp, 0, limit, 0, &NUM_P); P_MIN = PRIMES[0]; P_MAX = PRIMES[NUM_P-1]; } while ((mpz_cmp_ui(fobj->div_obj.gmp_n, 1) > 0) && (PRIMES[k] < limit) && (k < (uint32)NUM_P)) { q = (fp_digit)PRIMES[k]; r = mpz_tdiv_ui(fobj->div_obj.gmp_n, q); if (r != 0) k++; else { mpz_tdiv_q_ui(fobj->div_obj.gmp_n, fobj->div_obj.gmp_n, q); mpz_set_64(tmp, q); add_to_factor_list(fobj, tmp); #if BITS_PER_DIGIT == 64 logprint(flog,"div: found prime factor = %" PRIu64 "\n",q); #else logprint(flog,"div: found prime factor = %u\n",q); #endif if (print && (VFLAG > 0)) #if BITS_PER_DIGIT == 64 printf("div: found prime factor = %" PRIu64 "\n",q); #else printf("div: found prime factor = %u\n",q); #endif } } fclose(flog); mpz_clear(tmp); }
int mpz_perfect_power_p (mpz_srcptr u) { unsigned long int prime; unsigned long int n, n2; int i; unsigned long int rem; mpz_t u2, q; int exact; mp_size_t uns; mp_size_t usize = SIZ (u); TMP_DECL; if (mpz_cmpabs_ui (u, 1) <= 0) return 1; /* -1, 0, and +1 are perfect powers */ n2 = mpz_scan1 (u, 0); if (n2 == 1) return 0; /* 2 divides exactly once. */ TMP_MARK; uns = ABS (usize) - n2 / BITS_PER_MP_LIMB; MPZ_TMP_INIT (q, uns); MPZ_TMP_INIT (u2, uns); mpz_tdiv_q_2exp (u2, u, n2); mpz_abs (u2, u2); if (mpz_cmp_ui (u2, 1) == 0) { TMP_FREE; /* factoring completed; consistent power */ return ! (usize < 0 && POW2P(n2)); } if (isprime (n2)) goto n2prime; for (i = 1; primes[i] != 0; i++) { prime = primes[i]; if (mpz_cmp_ui (u2, prime) < 0) break; if (mpz_divisible_ui_p (u2, prime)) /* divisible by this prime? */ { rem = mpz_tdiv_q_ui (q, u2, prime * prime); if (rem != 0) { TMP_FREE; return 0; /* prime divides exactly once, reject */ } mpz_swap (q, u2); for (n = 2;;) { rem = mpz_tdiv_q_ui (q, u2, prime); if (rem != 0) break; mpz_swap (q, u2); n++; } n2 = gcd (n2, n); if (n2 == 1) { TMP_FREE; return 0; /* we have multiplicity 1 of some factor */ } if (mpz_cmp_ui (u2, 1) == 0) { TMP_FREE; /* factoring completed; consistent power */ return ! (usize < 0 && POW2P(n2)); } /* As soon as n2 becomes a prime number, stop factoring. Either we have u=x^n2 or u is not a perfect power. */ if (isprime (n2)) goto n2prime; } } if (n2 == 0) { /* We found no factors above; have to check all values of n. */ unsigned long int nth; for (nth = usize < 0 ? 3 : 2;; nth++) { if (! isprime (nth)) continue; #if 0 exact = mpz_padic_root (q, u2, nth, PTH); if (exact) #endif exact = mpz_root (q, u2, nth); if (exact) { TMP_FREE; return 1; } if (mpz_cmp_ui (q, SMALLEST_OMITTED_PRIME) < 0) { TMP_FREE; return 0; } } } else { unsigned long int nth; if (usize < 0 && POW2P(n2)) { TMP_FREE; return 0; } /* We found some factors above. We just need to consider values of n that divides n2. */ for (nth = 2; nth <= n2; nth++) { if (! isprime (nth)) continue; if (n2 % nth != 0) continue; #if 0 exact = mpz_padic_root (q, u2, nth, PTH); if (exact) #endif exact = mpz_root (q, u2, nth); if (exact) { if (! (usize < 0 && POW2P(nth))) { TMP_FREE; return 1; } } if (mpz_cmp_ui (q, SMALLEST_OMITTED_PRIME) < 0) { TMP_FREE; return 0; } } TMP_FREE; return 0; } n2prime: if (usize < 0 && POW2P(n2)) { TMP_FREE; return 0; } exact = mpz_root (NULL, u2, n2); TMP_FREE; return exact; }
int main(int argc, char **argv) { mpz_t year, tmp1, tmp2, tmp3, tmp4; unsigned long day_of_week = 0; uintmax_t month_min = 1, month_max = 12; int_fast8_t month_days = 0; const int_fast8_t months_days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; time_t t = time(NULL); char weekday[13] = {0}, weekdays[92] = {0}, month_name[13] = {0}; struct tm *time_struct = localtime(&t); setlocale(LC_ALL, ""); mpz_init(year); switch(argc) { case 1: mpz_set_ui(year, time_struct->tm_year + 1900); month_min = month_max = time_struct->tm_mon + 1; break; case 2: mpz_set_str(year, argv[1], 10); break; default: month_min = month_max = strtoumax(argv[1], NULL, 10); mpz_set_str(year, argv[2], 10); } if(mpz_sgn(year) < 1 || !month_min || month_min > 12) { fputs("http://opengroup.org/onlinepubs/9699919799/utilities/cal.html\n", stderr); exit(1); } for(int_fast8_t i = 0; i < 7; ++i) { time_struct->tm_wday = i; strftime(weekday, 13, "%a", time_struct); strcat(weekdays, weekday); strcat(weekdays, " "); } strcat(weekdays, "\n"); for(uintmax_t month = month_min; month <= month_max; ++month) { time_struct->tm_mon = month - 1; strftime(month_name, 13, "%b", time_struct); if(month > month_min) putchar('\n'); for(int_fast8_t i = (23 - strlen(mpz_get_str(NULL, 10, year))) / 2; i > 0; --i) putchar(' '); fputs(month_name, stdout); putchar(' '); printf("%s\n", mpz_get_str(NULL, 10, year)); fputs(weekdays, stdout); if(!mpz_cmp_ui(year, 1752) && month == 9) { fputs(" 1 2 14 15 16", stdout); fputs("17 18 19 20 21 22 23", stdout); fputs("24 25 26 27 28 29 30", stdout); } else { month_days = months_days[month - 1]; mpz_init(tmp1); mpz_init(tmp2); mpz_init(tmp3); mpz_init(tmp4); if(mpz_cmp_ui(year, 1752) > 0 || (!mpz_cmp_ui(year, 1752) && month > 9)) { /* Gregorian */ if(month == 2 && mpz_divisible_ui_p(year, 4) && (!mpz_divisible_ui_p(year, 100) || mpz_divisible_ui_p(year, 400))) month_days = 29; mpz_add_ui(tmp4, year, 4800 - (14 - month) / 12); mpz_tdiv_q_ui(tmp1, tmp4, 4); mpz_tdiv_q_ui(tmp2, tmp4, 100); mpz_tdiv_q_ui(tmp3, tmp4, 400); mpz_mul_ui(tmp4, tmp4, 365); mpz_add(tmp4, tmp4, tmp1); mpz_sub(tmp4, tmp4, tmp2); mpz_add(tmp4, tmp4, tmp3); mpz_add_ui(tmp4, tmp4, (153 * (month + 12 * ((14 - month) / 12) - 3) + 2) / 5); mpz_sub_ui(tmp4, tmp4, 32043); day_of_week = mpz_tdiv_ui(tmp4, 7); } else { /* Julian */ if(month == 2 && mpz_divisible_ui_p(year, 4)) month_days = 29; mpz_add_ui(tmp2, year, 4800 - (14 - month) / 12); mpz_tdiv_q_ui(tmp1, tmp2, 4); mpz_mul_ui(tmp2, tmp2, 365); mpz_add(tmp2, tmp2, tmp1); mpz_add_ui(tmp2, tmp2, (153 * (month + 12 * ((14 - month) / 12) - 3) + 2) / 5); mpz_sub_ui(tmp2, tmp2, 32081); day_of_week = mpz_tdiv_ui(tmp2, 7); } mpz_clear(tmp1); mpz_clear(tmp2); mpz_clear(tmp3); mpz_clear(tmp4); for(uint_fast8_t i = 0; i < day_of_week; ++i) fputs(" ", stdout); for(int_fast8_t i = 1; i <= month_days; ++i) { printf("%2u", i); ++day_of_week; if(i < month_days) fputs((day_of_week %= 7) ? " " : "\n", stdout); } } putchar('\n'); } mpz_clear(year); return 0; }
int main (int argc, char **argv) { mpz_t dividend; mpz_t quotient, remainder; mpz_t quotient2, remainder2; mpz_t temp; mp_size_t dividend_size; unsigned long divisor; int i; int reps = 10000; gmp_randstate_ptr rands; mpz_t bs; unsigned long bsi, size_range; unsigned long r_rq, r_q, r_r, r; tests_start (); rands = RANDS; mpz_init (bs); if (argc == 2) reps = atoi (argv[1]); mpz_init (dividend); mpz_init (quotient); mpz_init (remainder); mpz_init (quotient2); mpz_init (remainder2); mpz_init (temp); for (i = 0; i < reps; i++) { mpz_urandomb (bs, rands, 32); size_range = mpz_get_ui (bs) % 10 + 2; /* 0..2047 bit operands */ do { mpz_rrandomb (bs, rands, 64); divisor = mpz_get_ui (bs); } while (divisor == 0); mpz_urandomb (bs, rands, size_range); dividend_size = mpz_get_ui (bs); mpz_rrandomb (dividend, rands, dividend_size); mpz_urandomb (bs, rands, 2); bsi = mpz_get_ui (bs); if ((bsi & 1) != 0) mpz_neg (dividend, dividend); /* printf ("%ld\n", SIZ (dividend)); */ r_rq = mpz_tdiv_qr_ui (quotient, remainder, dividend, divisor); r_q = mpz_tdiv_q_ui (quotient2, dividend, divisor); r_r = mpz_tdiv_r_ui (remainder2, dividend, divisor); r = mpz_tdiv_ui (dividend, divisor); /* First determine that the quotients and remainders computed with different functions are equal. */ if (mpz_cmp (quotient, quotient2) != 0) dump_abort ("quotients from mpz_tdiv_qr_ui and mpz_tdiv_q_ui differ", dividend, divisor); if (mpz_cmp (remainder, remainder2) != 0) dump_abort ("remainders from mpz_tdiv_qr_ui and mpz_tdiv_r_ui differ", dividend, divisor); /* Check if the sign of the quotient is correct. */ if (mpz_cmp_ui (quotient, 0) != 0) if ((mpz_cmp_ui (quotient, 0) < 0) != (mpz_cmp_ui (dividend, 0) < 0)) dump_abort ("quotient sign wrong", dividend, divisor); /* Check if the remainder has the same sign as the dividend (quotient rounded towards 0). */ if (mpz_cmp_ui (remainder, 0) != 0) if ((mpz_cmp_ui (remainder, 0) < 0) != (mpz_cmp_ui (dividend, 0) < 0)) dump_abort ("remainder sign wrong", dividend, divisor); mpz_mul_ui (temp, quotient, divisor); mpz_add (temp, temp, remainder); if (mpz_cmp (temp, dividend) != 0) dump_abort ("n mod d != n - [n/d]*d", dividend, divisor); mpz_abs (remainder, remainder); if (mpz_cmp_ui (remainder, divisor) >= 0) dump_abort ("remainder greater than divisor", dividend, divisor); if (mpz_cmp_ui (remainder, r_rq) != 0) dump_abort ("remainder returned from mpz_tdiv_qr_ui is wrong", dividend, divisor); if (mpz_cmp_ui (remainder, r_q) != 0) dump_abort ("remainder returned from mpz_tdiv_q_ui is wrong", dividend, divisor); if (mpz_cmp_ui (remainder, r_r) != 0) dump_abort ("remainder returned from mpz_tdiv_r_ui is wrong", dividend, divisor); if (mpz_cmp_ui (remainder, r) != 0) dump_abort ("remainder returned from mpz_tdiv_ui is wrong", dividend, divisor); } mpz_clear (bs); mpz_clear (dividend); mpz_clear (quotient); mpz_clear (remainder); mpz_clear (quotient2); mpz_clear (remainder2); mpz_clear (temp); tests_end (); exit (0); }
int main(int argc, char** argv) { int my_rank, procs; MPI_Status status; mpz_t q, p, pq, n, gap, sqn; mpz_t *k; double *timearray; double begin, end; double time_spent; int done = 0, found = 0; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); MPI_Comm_size(MPI_COMM_WORLD, &procs); begin = MPI_Wtime(); mpz_init(n); mpz_init(q); mpz_init(p); mpz_init(pq); mpz_init(sqn); mpz_init(gap); mpz_set_str(n,argv[1],10); mpz_sqrt(sqn,n); mpz_set(gap, sqn); mpz_set_ui(p,1); mpz_nextprime(q, p); size_t mag = mpz_sizeinbase (gap, 10); mag=mag*procs; k = (mpz_t*)malloc(sizeof(mpz_t)*(mag+1)); mpz_t temp; mpz_init(temp); mpz_tdiv_q_ui(temp,gap,mag); for (int i=0;i<=mag;i++) { mpz_init(k[i]); mpz_mul_ui(k[i],temp,i); } mpz_set(k[mag],sqn); int counter=0; for (int i=my_rank; i<mag; i=i+procs) { mpz_set(q,k[i]); mpz_sub_ui(q,q,1); mpz_nextprime(q,q); while (( mpz_cmp(q,k[i+1]) <= 0 )&&(!done)&&(!found)&&(mpz_cmp(q,sqn)<=0)) {//finding the prime numbers counter++; if (counter%5000==0)MPI_Allreduce(&found, &done, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD); if (mpz_divisible_p(n,q)==0) {//if n is not divisible by q mpz_nextprime(q,q); continue; } //since it is divisible, try n/q and see if result is prime mpz_divexact(p,n,q); int reps; if (mpz_probab_prime_p(p,reps)!=0) { found = 1; done = 1; } else { mpz_nextprime(q,q); } }//done finding primes if (found || done) break; } end = MPI_Wtime(); if (found) { MPI_Allreduce(&found, &done, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD); gmp_printf("*************************\nP%d: Finished\np*q=n\np=%Zd q=%Zd n=%Zd\n*************************\n", my_rank,p,q,n); } else if (!done) { while (!done&&!found) MPI_Allreduce(&found, &done, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD); } time_spent = (double)(end - begin); if (my_rank!=0) { MPI_Send(&time_spent, sizeof(double),MPI_CHAR,0,0,MPI_COMM_WORLD); } else { timearray = (double*)malloc(sizeof(double)*procs); timearray[0] = time_spent; int j; for (j = 1; j<procs;j++) { double *ptr = timearray+j; MPI_Recv(ptr, sizeof(double),MPI_CHAR,j,0,MPI_COMM_WORLD,&status); } writeTime(argv[1],timearray,procs); free(timearray); } free(k); MPI_Finalize(); return 0; }
uint64 init_sieve(soe_staticdata_t *sdata) { int i,k; uint64 numclasses = sdata->numclasses; uint64 prodN = sdata->prodN; uint64 allocated_bytes = 0; uint64 lowlimit = sdata->orig_llimit; uint64 highlimit = sdata->orig_hlimit; uint64 numflags, numbytes, numlinebytes; //create the selection masks for (i=0;i<BITSINBYTE;i++) nmasks[i] = ~masks[i]; //allocate the residue classes. sdata->rclass = (uint32 *)malloc(numclasses * sizeof(uint32)); allocated_bytes += numclasses * sizeof(uint32); //find the residue classes k=0; for (i=1;i<prodN;i++) { if (spGCD(i,(uint64)prodN) == 1) { sdata->rclass[k] = (uint32)i; //printf("%u ",i); k++; } } sdata->min_sieved_val = 1ULL << 63; //temporarily set lowlimit to the first multiple of numclasses*prodN < lowlimit if (sdata->sieve_range == 0) { lowlimit = (lowlimit/(numclasses*prodN))*(numclasses*prodN); sdata->lowlimit = lowlimit; } else { mpz_t tmpz, tmpz2; mpz_init(tmpz); mpz_init(tmpz2); //the start of the range of interest is controlled by offset, not lowlimit //figure out how it needs to change to accomodate sieving mpz_tdiv_q_ui(tmpz, *sdata->offset, numclasses * prodN); mpz_mul_ui(tmpz, tmpz, numclasses * prodN); mpz_sub(tmpz2, *sdata->offset, tmpz); //raise the high limit by the amount the offset was lowered, so that //we allocate enough flags to cover the range of interest highlimit += mpz_get_ui(tmpz2); sdata->orig_hlimit += mpz_get_ui(tmpz2); //also raise the original lowlimit so that we don't include sieve primes //that we shouldn't when finalizing the process. sdata->orig_llimit += mpz_get_ui(tmpz2); //copy the new value to the pointer, which will get passed back to sieve_to_depth mpz_set(*sdata->offset, tmpz); mpz_clear(tmpz); mpz_clear(tmpz2); //set the lowlimit to 0; the real start of the range is controlled by offset sdata->lowlimit = 0; } //reallocate flag structure for wheel and block sieving //starting at lowlimit, we need a flag for every 'numresidues' numbers out of 'prodN' up to //limit. round limit up to make this a whole number. numflags = (highlimit - lowlimit)/prodN; numflags += ((numflags % prodN) != 0); numflags *= numclasses; //since we can pack 8 flags in a byte, we need numflags/8 bytes allocated. numbytes = numflags / BITSINBYTE + ((numflags % BITSINBYTE) != 0); //since there are N lines to sieve over, each line will contain (numflags/8)/N bytes //so round numflags/8 up to the nearest multiple of N numlinebytes = numbytes/numclasses + ((numbytes % numclasses) != 0); //we want an integer number of blocks, so round up to the nearest multiple of blocksize bytes i = 0; while (1) { i += BLOCKSIZE; if (i > numlinebytes) break; } numlinebytes = i; //all this rounding has likely changed the desired high limit. compute the new highlimit. //the orignial desired high limit is already recorded so the proper count will be returned. //todo... did we round too much? look into this. highlimit = (uint64)((uint64)numlinebytes * (uint64)prodN * (uint64)BITSINBYTE + lowlimit); sdata->highlimit = highlimit; sdata->numlinebytes = numlinebytes; //a block consists of BLOCKSIZE bytes of flags //which holds FLAGSIZE flags. sdata->blocks = numlinebytes/BLOCKSIZE; //each flag in a block is spaced prodN integers apart. record the resulting size of the //number line encoded in each block. sdata->blk_r = FLAGSIZE*prodN; //allocate space for the root of each sieve prime sdata->root = (int *)malloc(sdata->pboundi * sizeof(int)); allocated_bytes += sdata->pboundi * sizeof(uint32); if (sdata->root == NULL) { printf("error allocating roots\n"); exit(-1); } else { if (VFLAG > 2) printf("allocated %u bytes for roots\n",(uint32)(sdata->pboundi * sizeof(uint32))); } //compute the breakpoints at which we switch to other sieving methods if (sdata->pboundi > BUCKETSTARTI) { sdata->bucket_start_id = BUCKETSTARTI; sdata->num_bucket_primes = sdata->pboundi - sdata->bucket_start_id; } else { sdata->num_bucket_primes = 0; sdata->bucket_start_id = sdata->pboundi; } //any prime larger than this will only hit the interval once (in residue space) sdata->large_bucket_start_prime = sdata->blocks * FLAGSIZE; //block ranges for the various line sieving scenarios: //2 classes: block range = 1572864, approx min prime index = 119275 //8 classes: block range = 7864320, min prime index = 531290 //48 classes: block range = 55050240, min prime index = 3285304 //480 classes: block range = 605552640, min prime index = 31599827 sdata->inplace_start_id = sdata->pboundi; sdata->num_inplace_primes = 0; #if defined(INPLACE_BUCKET) switch (sdata->numclasses) { case 2: if (sdata->pboundi > 119275) { sdata->inplace_start_id = 119275; sdata->num_inplace_primes = sdata->pboundi - sdata->inplace_start_id; sdata->num_bucket_primes = sdata->inplace_start_id - sdata->bucket_start_id; } break; case 8: if (sdata->pboundi > 531290) { sdata->inplace_start_id = 531290; sdata->num_inplace_primes = sdata->pboundi - sdata->inplace_start_id; sdata->num_bucket_primes = sdata->inplace_start_id - sdata->bucket_start_id; } break; case 48: if (sdata->pboundi > 3285304) { sdata->inplace_start_id = 3285304; sdata->num_inplace_primes = sdata->pboundi - sdata->inplace_start_id; sdata->num_bucket_primes = sdata->inplace_start_id - sdata->bucket_start_id; } break; case 480: if (sdata->pboundi > 31599827) { sdata->inplace_start_id = 31599827; sdata->num_inplace_primes = sdata->pboundi - sdata->inplace_start_id; sdata->num_bucket_primes = sdata->inplace_start_id - sdata->bucket_start_id; } break; default: printf("unknown number of classes\n"); exit(1); break; } // allocate data structures for inplace sieving if (sdata->num_inplace_primes > 0) { // set up a two dimensional array of pointers to elements of the sieving prime array // first dimension is block number // second dimension is class number // element is a pointer to a uint32 (a sieving prime) sdata->inplace_ptrs = (int **)malloc(sdata->blocks * sizeof(int *)); for (i=0; i<sdata->blocks; i++) { int j; sdata->inplace_ptrs[i] = (int *)malloc(sdata->numclasses * sizeof(int)); for (j=0; j<sdata->numclasses; j++) sdata->inplace_ptrs[i][j] = -1; } // allocate space for the inplace data we'll need sdata->inplace_data = (soe_inplace_p *)malloc( sdata->num_inplace_primes * sizeof(soe_inplace_p)); } #endif //these are only used by the bucket sieve sdata->lower_mod_prime = (uint32 *)malloc(sdata->num_bucket_primes * sizeof(uint32)); allocated_bytes += sdata->num_bucket_primes * sizeof(uint32); if (sdata->lower_mod_prime == NULL) { printf("error allocating lower mod prime\n"); exit(-1); } else { if (VFLAG > 2) printf("allocated %u bytes for lower mod prime\n", (uint32)sdata->num_bucket_primes * (uint32)sizeof(uint32)); } //allocate all of the lines if we are computing primes. if we are //only counting them, just create the pointer array - lines will //be allocated as needed during sieving sdata->lines = (uint8 **)malloc(sdata->numclasses * sizeof(uint8 *)); numbytes = 0; if (sdata->only_count) { //don't allocate anything now, but //provide an figure for the memory that will be allocated later numbytes = numlinebytes * sizeof(uint8) * THREADS; } else { //actually allocate all of the lines for (i=0; i<sdata->numclasses; i++) { sdata->lines[i] = (uint8 *)malloc(numlinebytes * sizeof(uint8)); if (sdata->lines[i] == NULL) { printf("error allocated sieve lines\n"); exit(-1); } numbytes += numlinebytes * sizeof(uint8); } } if (VFLAG > 2) printf("allocated %" PRIu64 " bytes for sieve lines\n",numbytes); allocated_bytes += numbytes; return allocated_bytes; }