diff --git a/src/lexer.h b/src/lexer.h
index ec20723eeb0c4c07e11c387e1db1be07ce8fc146..ac317fc47973578a58550e97a912553921d75c0a 100644
--- a/src/lexer.h
+++ b/src/lexer.h
@@ -1,5 +1,5 @@
 /*
- * $Id: lexer.h,v 1.8 1999/10/23 06:51:28 hubbe Exp $
+ * $Id: lexer.h,v 1.9 1999/10/26 17:52:47 noring Exp $
  *
  * Lexical analyzer template.
  * Based on lex.c 1.62
@@ -413,19 +413,30 @@ static int low_yylex(YYSTYPE *yylval)
       return c;
   
     case '0':
-      if(GOBBLE('x') || GOBBLE('X'))
+    {
+      int base = 0;
+      
+      if(GOBBLE('b') || GOBBLE('B'))
       {
+	base = 2;
+	goto read_based_number;
+      }
+      else if(GOBBLE('x') || GOBBLE('X'))
+      {
+	base = 16;
+      read_based_number:
 	debug_malloc_pass( yylval->n=mkintnode(0) );
 	wide_string_to_svalue_inumber(&yylval->n->u.sval,
 				      lex.pos,
 				      (void **)&lex.pos,
-				      16,
+				      base,
 				      0,
 				      SHIFT);
 	free_string(yylval->n->type);
 	yylval->n->type=get_type_of_svalue(&yylval->n->u.sval);
 	return F_NUMBER;
       }
+    }
   
     case '1': case '2': case '3': case '4':
     case '5': case '6': case '7': case '8': case '9':
diff --git a/src/modules/Gmp/mpz_glue.c b/src/modules/Gmp/mpz_glue.c
index 98e4130207eeec99044bf440f972125aca5c3f69..7da2aa91d7c7505ee4cb5bcf7349ae064e35f75a 100644
--- a/src/modules/Gmp/mpz_glue.c
+++ b/src/modules/Gmp/mpz_glue.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: mpz_glue.c,v 1.57 1999/10/26 06:30:49 hubbe Exp $");
+RCSID("$Id: mpz_glue.c,v 1.58 1999/10/26 17:52:52 noring Exp $");
 #include "gmp_machine.h"
 
 #if defined(HAVE_GMP2_GMP_H) && defined(HAVE_LIBGMP2)
@@ -64,8 +64,32 @@ static void get_mpz_from_digits(MP_INT *tmp,
 {
   if(!base || ((base >= 2) && (base <= 36)))
   {
-    if (mpz_set_str(tmp, digits->str, base))
+    int offset = 0;
+    
+    /* We need to fix the case with binary 0b101... and -0b101... numbers. */
+    if(base == 0 && digits->len > 2)
+    {
+      if(INDEX_CHARP(digits->str, 0, digits->size_shift) == '-')
+	offset += 1;
+      if((INDEX_CHARP(digits->str, offset, digits->size_shift) == '0') &&
+	 ((INDEX_CHARP(digits->str, offset+1, digits->size_shift) == 'b') ||
+	  (INDEX_CHARP(digits->str, offset+1, digits->size_shift) == 'B')))
+      {
+	offset += 2;
+	base = 2;
+      }
+      else
+	offset = 0;
+    }
+
+    if (mpz_set_str(tmp, digits->str + offset, base))
       error("invalid digits, cannot convert to mpz");
+
+    if(offset == 3)
+    {
+      /* This means a negative binary number. */
+      mpz_neg(tmp, tmp);
+    }
   }
   else if(base == 256)
   {
@@ -310,8 +334,12 @@ static void mpzmod__sprintf(INT32 args)
     mask_shift += 1;
     /* Fall-through. */
   case 'o':
-    base += 8;
-    mask_shift += 3;
+    base += 6;
+    mask_shift += 2;
+    /* Fall-through. */
+  case 'b':
+    base += 2;
+    mask_shift += 1;
 
     if(precision > 0)
     {
@@ -392,8 +420,18 @@ static void mpzmod_cast(INT32 args)
   case 'i':
     if(!strncmp(s->str, "int", 3))
     {
+#ifdef AUTO_BIGNUM_XXXX
+      /* FIXME 1: Do we need to free the string?  Looking
+	 at the case with 'o' makes this confusing...
+
+	 FIXME 2: The run-time cast checking does not work
+	 properly with bignums. Take a look at row 209 and
+	 226 in opcodes.c for more examples on this. */
+      push_object(this_object());
+#else
       free_string(s);
       mpzmod_get_int(0);
+#endif /* AUTO_BIGNUM */
       return;
     }
     break;
diff --git a/src/opcodes.c b/src/opcodes.c
index fc230943cd0d1f29f8c3a1e578847d8264ace699..7752a66e27e20ab5f036b46a15e0ea391703b3c0 100644
--- a/src/opcodes.c
+++ b/src/opcodes.c
@@ -25,7 +25,7 @@
 #include "security.h"
 #include "bignum.h"
 
-RCSID("$Id: opcodes.c,v 1.51 1999/10/25 10:18:46 hubbe Exp $");
+RCSID("$Id: opcodes.c,v 1.52 1999/10/26 17:52:48 noring Exp $");
 
 void index_no_free(struct svalue *to,struct svalue *what,struct svalue *ind)
 {
@@ -903,6 +903,7 @@ static INT32 really_low_sscanf(char *input,
 	     }
 	  break;
 
+        case 'b':
         case 'o':
         case 'd':
         case 'x':
@@ -920,6 +921,7 @@ static INT32 really_low_sscanf(char *input,
 
 	  switch(match[cnt])
 	  {
+	  case 'b': base =  2; break;
 	  case 'o': base =  8; break;
 	  case 'd': base = 10; break;
 	  case 'x': base = 16; break;
diff --git a/src/stralloc.c b/src/stralloc.c
index e4ef4d28cba90b08854e9219986c8912537da2ac..61cfa6a431618a6935ca62ba62afe6fe6dca4be2 100644
--- a/src/stralloc.c
+++ b/src/stralloc.c
@@ -25,7 +25,7 @@
 #define HUGE HUGE_VAL
 #endif /*!HUGE*/
 
-RCSID("$Id: stralloc.c,v 1.71 1999/10/24 01:08:39 noring Exp $");
+RCSID("$Id: stralloc.c,v 1.72 1999/10/26 17:52:49 noring Exp $");
 
 #define BEGIN_HASH_SIZE 997
 #define MAX_AVG_LINK_LENGTH 3
@@ -1888,6 +1888,8 @@ int pcharp_to_svalue_inumber(struct svalue *r,
       base = 10;
     else if(INDEX_PCHARP(str,1) == 'x' || INDEX_PCHARP(str,1) == 'X')
       base = 16;
+    else if(INDEX_PCHARP(str,1) == 'b' || INDEX_PCHARP(str,1) == 'B')
+      base = 2;
     else
       base = 8;
   }
@@ -1899,10 +1901,11 @@ int pcharp_to_svalue_inumber(struct svalue *r,
   if(!isalnum(c) || (xx = DIGIT(c)) >= base)
     return 0;   /* No number formed. */
   
-  if(implicit_base && base == 16 && c == '0' &&
+  if(implicit_base && c == '0' &&
      INDEX_PCHARP(str,2) < 256 && /* Don't trust isxdigit... */
      isxdigit(INDEX_PCHARP(str,2)) &&
-      (INDEX_PCHARP(str,1) == 'x' || INDEX_PCHARP(str,1) == 'X'))
+     ((base==16 && (INDEX_PCHARP(str,1)=='x' || INDEX_PCHARP(str,1)=='X')) ||
+      (base==2 && (INDEX_PCHARP(str,1)=='b' || INDEX_PCHARP(str,1)=='B'))))
   {
     /* Skip over leading "0x" or "0X". */
     INC_PCHARP(str,2);
diff --git a/src/testsuite.in b/src/testsuite.in
index 6445a9120faa9b4602845a6a698d66b026b05a96..aebba107e41b7eacbbe680a0a652aeb062ee50cc 100644
--- a/src/testsuite.in
+++ b/src/testsuite.in
@@ -1,4 +1,4 @@
-test_true([["$Id: testsuite.in,v 1.208 1999/10/25 10:26:25 hubbe Exp $"]])
+test_true([["$Id: testsuite.in,v 1.209 1999/10/26 17:52:50 noring Exp $"]])
 
 cond([[all_constants()->_verify_internals]],
 [[
@@ -26,6 +26,11 @@ bar"]],[["foo\nbar"]])
 test_true([[stringp(#string "Makefile")]])
 test_any([[class Bar { array(int) foo = ({}); }; class Foo { inherit Bar; array(int) foo = ({1}); }; return sizeof(Foo()->foo);]],1)
 
+test_eq(8, 0b1000)
+test_eq(-8, -0b1000)
+test_eq(16, 0b10000)
+test_eq(-16, -0b10000)
+
 test_eval_error([[mixed x; return mkmapping(x,x)]])
 
 test_any([[return class Z {
@@ -1314,6 +1319,9 @@ cond([[ sizeof( cpp("__AUTO_BIGNUM__")/"__AUTO_BIGNUM__" ) == 1 ]],
   test_eq("-335812727629498640265", [[ (string)-0x123456789123456789 ]])
   test_eq("718046312823", [[ (string)012345671234567 ]])
   test_eq("-718046312823", [[ (string)-012345671234567 ]])
+  test_eq("", [[ (string)012345671234567 ]])
+  test_eq("1125899906842624", [[ (string)0b100000000000000000000000000000000000000000000000000 ]])
+  test_eq("-1125899906842624", [[ (string)-0b100000000000000000000000000000000000000000000000000 ]])
     
   // These numbers should be ordinary integers.
   test_false([[ objectp(-0x80000000) ]])
@@ -1410,6 +1418,10 @@ cond([[ sizeof( cpp("__AUTO_BIGNUM__")/"__AUTO_BIGNUM__" ) == 1 ]],
 	   [[ (string)array_sscanf("1234567012345670", "%o")[0] ]])
   test_eq("45954944846776",
 	   [[ (string)array_sscanf("01234567012345670", "%i")[0] ]])
+  test_eq("11", [[ (string)array_sscanf("1011", "%b")[0] ]])
+  test_eq("1125968643114208", [[ (string)array_sscanf("100000000000001000000000001000000000100010011100000", "%b")[0] ]])
+  test_eq("11", [[ (string)array_sscanf("0b1011", "%i")[0] ]])
+  test_eq("1125968643114208", [[ (string)array_sscanf("0b100000000000001000000000001000000000100010011100000", "%i")[0] ]])
   
   test_eq("-12345678901234567890",
 	   [[ (string)array_sscanf("-12345678901234567890", "%d")[0] ]])
@@ -1421,10 +1433,17 @@ cond([[ sizeof( cpp("__AUTO_BIGNUM__")/"__AUTO_BIGNUM__" ) == 1 ]],
 	   [[ (string)array_sscanf("-1234567012345670", "%o")[0] ]])
   test_eq("-45954944846776",
 	   [[ (string)array_sscanf("-01234567012345670", "%i")[0] ]])
+  test_eq("-11", [[ (string)array_sscanf("-1011", "%b")[0] ]])
+  test_eq("-1125968643114208", [[ (string)array_sscanf("-100000000000001000000000001000000000100010011100000", "%b")[0] ]])
+  test_eq("-11", [[ (string)array_sscanf("-0b1011", "%i")[0] ]])
+  test_eq("-1125968643114208", [[ (string)array_sscanf("-0b100000000000001000000000001000000000100010011100000", "%i")[0] ]])
 
   test_equal([[ ({ 0, 118 }) ]], [[ array_sscanf("0x76", "%xx%x") ]])
   test_equal([[ ({ 0, 557239244978618154304871 }) ]],
              [[ array_sscanf("0x76000000000001234567", "%xx%x") ]])
+
+  test_equal(471100000000000000000000000000000000000000000000042,
+             (int)(mixed)471100000000000000000000000000000000000000000000042)
 ]])
 
 cond([[ sizeof( cpp("__AUTO_BIGNUM__")/"__AUTO_BIGNUM__" ) == 1 ]],