if (rhat < b) goto again;
}
-#define SUB_MUL_BORROW
#ifdef ORIGINAL
// Multiply and subtract.
k = 0;
#elif defined(SUB_MUL_BORROW)
(void)p; // shut up unused variable warning
+ // Multiply and subtract.
+ uint32_t borrow = 0;
+ for(int i = 0; i <= n; i++) {
+ uint32_t vn_i = i < n ? vn[i] : 0;
+ uint64_t value = un[i + j] - (uint64_t)qhat * vn_i - borrow;
+ borrow = -(uint32_t)(value >> 32);
+ un[i + j] = (uint32_t)value;
+ }
+ bool need_fixup = borrow != 0;
+#elif defined(MUL_RSUB_CARRY)
+ (void)p; // shut up unused variable warning
+
+ // Multiply and subtract.
+ uint32_t carry = 1;
+ for(int i = 0; i <= n; i++) {
+ uint32_t vn_i = i < n ? vn[i] : 0;
+ uint64_t result = un[i + j] + ~((uint64_t)qhat * vn_i) + carry;
+ uint32_t result_high = result >> 32;
+ if(carry <= 1)
+ result_high++;
+ carry = result_high;
+ un[i + j] = (uint32_t)result;
+ }
+ bool need_fixup = carry != 1;
+#elif defined(SUB_MUL_BORROW_2_STAGE)
+ (void)p; // shut up unused variable warning
+
// Multiply and subtract.
uint32_t borrow = 0;
uint32_t phi[2000]; // plenty space
un[i + j] = (uint32_t)value;
}
bool need_fixup = borrow != 0;
-#elif defined(MUL_RSUB_CARRY)
+#elif defined(MUL_RSUB_CARRY_2_STAGE)
(void)p; // shut up unused variable warning
// Multiply and subtract.
un[i + j] = (uint32_t)result;
}
bool need_fixup = carry != 1;
-#elif defined(MUL_RSUB_CARRY1)
+#elif defined(MUL_RSUB_CARRY_2_STAGE1)
(void)p; // shut up unused variable warning
// Multiply and subtract.
}
bool need_fixup = carry != 1;
#else
-#error need to define one of ORIGINAL, SUB_MUL_BORROW, or MUL_RSUB_CARRY
+#error need to choose one of the algorithm options; e.g. -DORIGINAL
#endif
q[j] = qhat; // Store quotient digit.