progs/perftest.c: Use from Glibc syscall numbers.
[catacomb] / math / mp-arith.c
index 61780b0..048f4c6 100644 (file)
@@ -667,10 +667,41 @@ mp *mp_odd(mp *d, mp *m, size_t *s)
   return (mp_lsr(d, m, ss));
 }
 
+/* --- @mp_leastcongruent@ --- *
+ *
+ * Arguments:  @mp *d@ = pointer to destination
+ *             @mp *b@ = lower bound
+ *             @mp *r@ = representative
+ *             @mp *m@ = modulus
+ *
+ * Returns:    The smallest integer %$x \equiv r \pmod{m}$% such that
+ *             %$x \ge b$%.
+ */
+
+mp *mp_leastcongruent(mp *d, mp *b, mp *r, mp *m)
+{
+  /* --- Strategy --- *
+   *
+   * Start by finding %$u \equiv b - r \pmod{m}$% with %$0 < u \le m$%.  Then
+   * %$b \le x = b + m - u < b + m$%, and %$x \equiv r \pmod{m}$% as
+   * required.
+   */
+
+  MP_COPY(b); MP_COPY(m);
+  d = mp_sub(d, b, r);
+  mp_div(0, &d, d, m);
+  if (MP_ZEROP(d)) { MP_DROP(d); d = MP_COPY(b); }
+  else { d = mp_sub(d, b, d); d = mp_add(d, d, m); }
+  MP_DROP(b); MP_DROP(m);
+  return (d);
+}
+
 /*----- Test rig ----------------------------------------------------------*/
 
 #ifdef TEST_RIG
 
+#include <mLib/macros.h>
+
 static int verify(const char *op, mp *expect, mp *result, mp *a, mp *b)
 {
   if (!MP_EQ(expect, result)) {
@@ -758,11 +789,11 @@ MPX_DOBIN(DO)
   mp *r = *(mp **)v[3].buf;
   mp *c;
 
-  if (strcmp(v[0].buf, "and") == 0) op = 1;
-  else if (strcmp(v[0].buf, "or") == 0) op = 7;
-  else if (strcmp(v[0].buf, "nand") == 0) op = 14;
-  else if (strcmp(v[0].buf, "nor") == 0) op = 8;
-  else if (strcmp(v[0].buf, "xor") == 0) op = 6;
+  if (STRCMP(v[0].buf, ==, "and")) op = 1;
+  else if (STRCMP(v[0].buf, ==, "or")) op = 7;
+  else if (STRCMP(v[0].buf, ==, "nand")) op = 14;
+  else if (STRCMP(v[0].buf, ==, "nor")) op = 8;
+  else if (STRCMP(v[0].buf, ==, "xor")) op = 6;
   else {
     char *p = v[0].buf;
     while (*p) {