int gnc_numeric_compare(gnc_numeric a, gnc_numeric b) { gint64 aa, bb; qofint128 l, r; if (gnc_numeric_check(a) || gnc_numeric_check(b)) { return 0; } if (a.denom == b.denom) { if (a.num == b.num) return 0; if (a.num > b.num) return 1; return -1; } if ((a.denom > 0) && (b.denom > 0)) { /* Avoid overflows using 128-bit intermediate math */ l = mult128 (a.num, b.denom); r = mult128 (b.num, a.denom); return cmp128 (l, r); } if (a.denom < 0) a.denom *= -1; if (b.denom < 0) b.denom *= -1; /* BUG: Possible overflow here.. Also, doesn't properly deal with * reciprocal denominators. */ aa = a.num * a.denom; bb = b.num * b.denom; if (aa == bb) return 0; if (aa > bb) return 1; return -1; }
/*------------------------------------------------------------------------*/ static uint32 sieve_lattice_batch(msieve_obj *obj, lattice_fb_t *L) { uint32 i, j, k; p_soa_var_t * p_array = (p_soa_var_t *)L->p_array; p_soa_var_t * q_array = (p_soa_var_t *)L->q_array; uint32 num_poly = L->poly->num_poly; uint32 num_p = p_array->num_p; for (i = 0; i < q_array->num_p; i++) { uint64 q = q_array->p[i]; uint128 q2 = wide_sqr64(q); uint32 q2_w = montmul32_w(q2.w[0]); uint128 q2_r = montmul128_r(q2); uint32 num_p_done = 0; time_t curr_time; double elapsed; while (num_p_done < num_p) { uint64 *plist = p_array->p + num_p_done; uint128 pinvlist[INVERT_BATCH_SIZE]; uint32 curr_num_p = MIN(INVERT_BATCH_SIZE, num_p - num_p_done); batch_invert(plist, curr_num_p, pinvlist, q2, q2_r, q2_w); for (j = 0; j < curr_num_p; j++) { uint64 p = plist[j]; uint128 pinv = pinvlist[j]; uint64 lattice_size = p_array->lattice_size[num_p_done+j]; uint128 test1; test1.w[0] = (uint32)lattice_size; test1.w[1] = (uint32)(lattice_size >> 32); test1.w[2] = 0; test1.w[3] = 0; for (k = 0; k < num_poly; k++) { uint128 qroot, proot, res; qroot = q_array->roots[k][i]; proot = p_array->roots[k][num_p_done+j]; res = montmul128(pinv, modsub128(qroot, proot, q2), q2, q2_w); if (cmp128(res, test1) < 0) { handle_collision(L->poly, k, p, proot, res, q); } } } num_p_done += curr_num_p; } if (obj->flags & MSIEVE_FLAG_STOP_SIEVING) return 1; curr_time = time(NULL); elapsed = curr_time - L->start_time; if (elapsed > L->deadline) return 1; } return 0; }