integer * integer_suba(integer * data, integer * y) { int cmp; integer *q = NULL; if (y->len_of_integer == 0) return data; if (data->len_of_integer == 0) { integer_assign(data, y); return data; } cmp = integer_abscmp(data, y); if (cmp == 0 && data->sign_of_integer == y->sign_of_integer) { integer_clear(data); return data; } if (cmp == 0 && data->sign_of_integer != y->sign_of_integer) { integer_lshifta(data, 1); return data; } if (cmp == 1 && data->sign_of_integer == y->sign_of_integer) { integer_ssub(data, y); return data; } if (cmp == 1 && data->sign_of_integer != y->sign_of_integer) { integer_sadd(data, y); return data; } if (cmp == -1 && data->sign_of_integer == y->sign_of_integer) { q = integer_copy(data); integer_assign(data, y); data->sign_of_integer = !data->sign_of_integer; integer_ssub(data, q); integer_destroy(q); return data; } if (cmp == -1 && data->sign_of_integer == y->sign_of_integer) { integer_sadd(data, y); return data; } return data; }
void coefficient_pp_cont(const lp_polynomial_context_t* ctx, coefficient_t* pp, coefficient_t* cont, const coefficient_t* C) { TRACE("coefficient", "coefficient_pp_cont()\n"); STAT(coefficient, pp_cont) ++; if (trace_is_enabled("coefficient")) { tracef("C = "); coefficient_print(ctx, C, trace_out); tracef("\n"); } assert(ctx->K == lp_Z); int special = coefficient_pp_cont_special(ctx, pp, cont, C); if (special) { return; } switch (C->type) { case COEFFICIENT_NUMERIC: if (cont) { if (cont->type == COEFFICIENT_POLYNOMIAL) { coefficient_destruct(cont); coefficient_construct_copy(ctx, cont, C); } else { integer_assign(ctx->K, &cont->value.num, &C->value.num); } } if (pp) { if (pp->type == COEFFICIENT_POLYNOMIAL) { coefficient_destruct(pp); coefficient_construct_from_int(ctx, pp, 1); } else { integer_assign_int(ctx->K, &pp->value.num, 1); } } break; case COEFFICIENT_POLYNOMIAL: { int i; coefficient_t gcd; // Compute the gcd of coefficients starting with LC coefficient_construct_copy(ctx, &gcd, coefficient_lc(C)); // Make if positive in case it's the only one if (coefficient_lc_sgn(ctx, &gcd) < 0) { coefficient_neg(ctx, &gcd, &gcd); } // Compute the rest of the gcd for (i = SIZE(C)-2; i >= 0 ; -- i) { if (!coefficient_is_zero(ctx, COEFF(C, i))) { coefficient_gcd(ctx, &gcd, &gcd, COEFF(C, i)); if (coefficient_is_one(ctx, &gcd)) { break; } } } // GCD is positive, so if the leading coefficient of C is negative, flip it if (coefficient_lc_sgn(ctx, C) < 0) { coefficient_neg(ctx, &gcd, &gcd); } if (pp) { // Now compute the pp coefficient_div(ctx, pp, C, &gcd); assert(coefficient_is_normalized(ctx, pp)); } if (cont) { coefficient_swap(&gcd, cont); assert(coefficient_is_normalized(ctx, cont)); } coefficient_destruct(&gcd); break; } default: assert(0); break; } if (trace_is_enabled("coefficient")) { tracef("coefficient_pp_cont() => "); if (pp) { tracef("pp = "); coefficient_print(ctx, pp, trace_out); tracef("\n"); } if (cont) { tracef("cont = "); coefficient_print(ctx, cont, trace_out); tracef("\n"); } } }