Fix fencepost bugs in binary radix writing.
[u/mdw/catacomb] / mptext.c
index c479d78..40e1764 100644 (file)
--- a/mptext.c
+++ b/mptext.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: mptext.c,v 1.12 2002/01/13 19:51:18 mdw Exp $
+ * $Id: mptext.c,v 1.15 2002/10/15 19:18:15 mdw Exp $
  *
  * Textual representation of multiprecision numbers
  *
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: mptext.c,v $
+ * Revision 1.15  2002/10/15 19:18:15  mdw
+ * Fix fencepost bugs in binary radix writing.
+ *
+ * Revision 1.14  2002/10/09 00:33:44  mdw
+ * Allow `0o' and `0b' prefixes for octal and binary (from Haskell)
+ *
+ * Revision 1.13  2002/10/09 00:21:06  mdw
+ * Allow user-specified `r_xx' bases to be up to 62.
+ *
  * Revision 1.12  2002/01/13 19:51:18  mdw
  * Extend the textual format to bases up to 62 by distinguishing case.
  *
@@ -207,12 +216,22 @@ mp *mp_read(mp *m, int radix, const mptext_ops *ops, void *p)
     r = 0;
   } else {
     ch = ops->get(p);
-    if (ch == 'x') {
-      ch = ops->get(p);
-      rd = 16;
-    } else {
-      rd = 8;
-      f |= f_ok;
+    switch (ch) {
+      case 'x':
+       rd = 16;
+       goto prefix;
+      case 'o':
+       rd = 8;
+       goto prefix;
+      case 'b':
+       rd = 2;
+       goto prefix;
+      prefix:
+       ch = ops->get(p);
+       break;
+      default:
+       rd = 8;
+       f |= f_ok;
     }
     r = -1;
   }
@@ -339,7 +358,7 @@ restart:
 
     /* --- An underscore indicates a numbered base --- */
 
-    if (ch == '_' && r > 0 && r <= 36) {
+    if (ch == '_' && r > 0 && r <= 62) {
       unsigned i;
 
       /* --- Clear out the stacks --- */
@@ -613,11 +632,12 @@ static int binary(mp *m, int bit, int radix, const mptext_ops *ops, void *p)
   /* --- Work out where to start --- */
 
   n = mp_bits(m);
-  n += bit - (n % bit);
+  if (n % bit)
+    n += bit - (n % bit);
   b = n % MPW_BITS;
   n /= MPW_BITS;
-  
-  if (n > MP_LEN(m)) {
+
+  if (n >= MP_LEN(m)) {
     n--;
     b += MPW_BITS;
   }
@@ -688,6 +708,9 @@ int mp_write(mp *m, int radix, const mptext_ops *ops, void *p)
 {
   int rc;
 
+  if (MP_EQ(m, MP_ZERO))
+    return (ops->put("0", 1, p));
+
   /* --- Set various things up --- */
 
   m = MP_COPY(m);