+ // Partially factored cases (to avoid expanding large expressions)
+ if (is_ex_exactly_of_type(a, mul)) {
+ if (is_ex_exactly_of_type(b, mul) && b.nops() > a.nops())
+ goto factored_b;
+factored_a:
+ ex g = _ex1();
+ ex acc_ca = _ex1();
+ ex part_b = b;
+ for (int i=0; i<a.nops(); i++) {
+ ex part_ca, part_cb;
+ g *= gcd(a.op(i), part_b, &part_ca, &part_cb, check_args);
+ acc_ca *= part_ca;
+ part_b = part_cb;
+ }
+ if (ca)
+ *ca = acc_ca;
+ if (cb) {
+ if (!divide(b, g, *cb))
+ throw(std::runtime_error("invalid expression in gcd(), division failed"));
+ }
+ return g;
+ } else if (is_ex_exactly_of_type(b, mul)) {
+ if (is_ex_exactly_of_type(a, mul) && a.nops() > b.nops())
+ goto factored_a;
+factored_b:
+ ex g = _ex1();
+ ex acc_cb = _ex1();
+ ex part_a = a;
+ for (int i=0; i<b.nops(); i++) {
+ ex part_ca, part_cb;
+ g *= gcd(part_a, b.op(i), &part_ca, &part_cb, check_args);
+ acc_cb *= part_cb;
+ part_a = part_ca;
+ }
+ if (ca) {
+ if (!divide(a, g, *ca))
+ throw(std::runtime_error("invalid expression in gcd(), division failed"));
+ }
+ if (cb)
+ *cb = acc_cb;
+ return g;
+ }
+