diff --git a/src/modules/gmpmod/doc/mpz b/src/modules/gmpmod/doc/mpz
index 2e85831a419b5f09e61c1995a70598408d466585..2b4c0bc67e9772761fb52f512397cf08b2198f03 100644
--- a/src/modules/gmpmod/doc/mpz
+++ b/src/modules/gmpmod/doc/mpz
@@ -18,15 +18,20 @@ NAME
 	create - initialize a bignum
 
 SYNTAX
-	object clone((program)"/precompiled/mpz");
+	object Mpz();
 	or
-	object clone((program)"/precompiled/mpz",int|object|string|float i);
+	object Mpz(int|object|float i);
+	or
+	object Mpz(string digits, int base);
+	
 
 DESCRIPTION
 	When cloning an mpz it is by default initalized to zero. However,
 	you can give a second argument to clone to initialize the new
 	object to that value. The argument can be an int, float another
-	mpz object, or a string containing an ascii number.
+	mpz object, or a string containing an ascii number. You can also
+	give the number in the string in another base by specifying the
+	base as a second argument. Valid bases are 2-36 and 256.
 
 SEE ALSO
 	builtin/clone
@@ -96,3 +101,36 @@ SEE ALSO
 	cast
 
 ============================================================================
+NAME
+	digits - convert mpz to a string
+
+SYNTAX
+	string mpz->digits();
+	or
+	string mpz->digits(int base);
+
+DESCRIPTION
+	This function converts an mpz to a string. If a base is given the
+	number will be represented in that base. Valid bases are 2-36 and
+	256. The default base is 10.
+
+SEE ALSO
+	mpz->cast
+
+============================================================================
+NAME
+	size - how long is a number
+
+SYNTAX
+	string mpz->size();
+	or
+	string mpz->size(int base);
+
+DESCRIPTION
+	This function returns how long the mpz would be represented in the
+	specified base. The default base is 2.
+
+SEE ALSO
+	mpz->digits
+
+============================================================================
diff --git a/src/modules/gmpmod/mpz_glue.c b/src/modules/gmpmod/mpz_glue.c
index 939a1e0933fdd6695a505cc0a58256f40553b859..d15900eb820f3271e6a225aae70c76b28a34b55a 100644
--- a/src/modules/gmpmod/mpz_glue.c
+++ b/src/modules/gmpmod/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.10 1996/11/18 02:47:51 nisse Exp $");
+RCSID("$Id: mpz_glue.c,v 1.11 1996/11/23 00:08:56 hubbe Exp $");
 #include "gmp_machine.h"
 #include "types.h"
 
@@ -33,46 +33,33 @@ RCSID("$Id: mpz_glue.c,v 1.10 1996/11/18 02:47:51 nisse Exp $");
 static struct program *mpzmod_program;
 
 static void get_mpz_from_digits(MP_INT *tmp,
-				struct svalue *s, struct svalue *b)
+				struct pike_string *digits,
+				int base)
 {
-  INT32 base;
-  struct pike_string *digits;
-
-  if (s->type != T_STRING)
-    error("wrong type, cannot convert to mpz");
-  digits = s->u.string;
-
-  if (b)
-    {
-      if  (b->type != T_INT)
-	error("wrong type, cannot convert to mpz");
-      base = b->u.integer;
-    }
-  else
-    base = 0;
-
-  if ((base == 0) || ((base >= 2) && (base <= 36)))
-    {
-      if (mpz_set_str(tmp, digits->str, base))
-	error("invalid digits, cannot convert to mpz");
-    }
-  else if (base == 256)
+  if(!base || ((base >= 2) && (base <= 36)))
+  {
+    if (mpz_set_str(tmp, digits->str, base))
+      error("invalid digits, cannot convert to mpz");
+  }
+  else if(base == 256)
+  {
+    
+    INT8 i;
+    mpz_t digit;
+    
+    mpz_init(digit);
+    mpz_set_ui(tmp, 0);
+    for (i = 0; i < digits->len; i++)
     {
-
-      INT8 i;
-      mpz_t digit;
-
-      mpz_init(digit);
-      mpz_set_ui(tmp, 0);
-      for (i = 0; i < digits->len; i++)
-	{
-	  mpz_set_ui(digit, EXTRACT_UCHAR(digits->str + i));
-	  mpz_mul_2exp(digit, digit, (digits->len - i - 1) * 8);
-	  mpz_ior(tmp, tmp, digit);
-	}
+      mpz_set_ui(digit, EXTRACT_UCHAR(digits->str + i));
+      mpz_mul_2exp(digit, digit, (digits->len - i - 1) * 8);
+      mpz_ior(tmp, tmp, digit);
     }
+  }
   else
+  {
     error("invalid base.\n");
+  }
 }
 
 static void get_new_mpz(MP_INT *tmp, struct svalue *s)
@@ -115,19 +102,29 @@ static void get_new_mpz(MP_INT *tmp, struct svalue *s)
 static void mpzmod_create(INT32 args)
 {
   switch(args)
-    {
-    case 1:
-      if ((sp-args)->type == T_STRING)
-	get_mpz_from_digits(THIS, sp-args, NULL);
-      else
-	get_new_mpz(THIS, sp-args);
-      break;
-    case 2: /* Args are string of digits and integer base */
-      if ((sp-args)->type != T_STRING)
-	error("wrong type, invalid string of digits");
-      get_mpz_from_digits(THIS, sp-args, sp-args+1);
-      break;
-    }
+  {
+  case 1:
+    if(sp[-args].type == T_STRING)
+      get_mpz_from_digits(THIS, sp[-args].u.string, 0);
+    else
+      get_new_mpz(THIS, sp-args);
+    break;
+
+  case 2: /* Args are string of digits and integer base */
+    if(sp[-args].type != T_STRING)
+      error("bad argument 1 for Mpz->create()");
+
+    if (sp[1-args].type != T_INT)
+      error("wrong type for base in Mpz->create()");
+
+    get_mpz_from_digits(THIS, sp[-args].u.string, sp[1-args].u.integer);
+    break;
+
+  default:
+    error("Too many arguments to Mpz->create()\n");
+
+  case 0:
+  }
   pop_n_elems(args);
 }
 
@@ -143,94 +140,93 @@ static void mpzmod_get_float(INT32 args)
   push_float((float)mpz_get_d(THIS));
 }
 
-static void mpzmod_get_string(INT32 args)
+static struct pike_string *low_get_digits(MP_INT *mpz, int base)
 {
   struct pike_string *s;
   INT32 len;
+  
+  if ( (base >= 2) && (base <= 36))
+  {
+    len = mpz_sizeinbase(mpz, base) + 2;
+    s = begin_shared_string(len);
+    mpz_get_str(s->str, base, mpz);
+    /* Find NULL character */
+    len-=4;
+    if (len < 0) len = 0;
+    while(s->str[len]) len++;
+    s->len=len;
+    s=end_shared_string(s);
+  }
+  else if (base == 256)
+  {
+    INT8 i;
+    mpz_t tmp;
+    
+    if (mpz_sgn(mpz) < 0)
+      error("only non-negative numbers can be converted to base 256.\n");
+    len = (mpz_sizeinbase(mpz, 2) + 7) / 8;
+    s = begin_shared_string(len);
+    mpz_init_set(tmp, mpz);
+    for (i = len - 1; i>= 0; i-- )
+    {
+      s->str[i] = mpz_get_ui(tmp) & 0xff;
+      mpz_tdiv_q_2exp(tmp, tmp, 8);
+    }
+    assert(mpz_sgn(tmp) == 0);
+    mpz_clear(tmp);
+    s = end_shared_string(s);
+  }
+  else
+  {
+    error("invalid base.\n");
+    return 0; /* Make GCC happy */
+  }
 
-  pop_n_elems(args);
-  len=mpz_sizeinbase(THIS,10);
-  len++; /* For a zero */
-  if(mpz_sgn(THIS) < 0) len++; /* For the - sign */
-
-  s=begin_shared_string(len);
-  mpz_get_str(s->str,10,THIS);
+  return s;
+}
 
-  len-=4;
-  if(len < 0) len = 0;
-  while(s->str[len]) len++;
-  s->len=len;
-  s=end_shared_string(s);
-  push_string(s);
+static void mpzmod_get_string(INT32 args)
+{
+  pop_n_elems(args);
+  push_string(low_get_digits(THIS, 10));
 }
 
 static void mpzmod_digits(INT32 args)
 {
-  int base;
-  struct pike_string *s;
-  INT32 len;
-
+  INT32 base;
   if (!args)
+  {
     base = 10;
+  }
   else
-    {
-      if (sp[-args].type != T_INT)
-	error("wrong type");
-      base = sp[-args].u.integer;
-    }
-  if ( (base >= 2) && (base <= 36))
-    {
-      len = mpz_sizeinbase(THIS, base) + 2;
-      s = begin_shared_string(len);
-      mpz_get_str(s->str, base, THIS);
-      /* Find NULL character */
-      len-=4;
-      if (len < 0) len = 0;
-      while(s->str[len]) len++;
-      s->len=len;
-      s=end_shared_string(s);
-    }
-  else if (base == 256)
-    {
-      INT8 i;
-      mpz_t tmp;
-      
-      if (mpz_sgn(THIS) < 0)
-	error("only non-negative numbers can be converted to base 256.\n");
-      len = (mpz_sizeinbase(THIS, 2) + 7) / 8;
-      s = begin_shared_string(len);
-      mpz_init_set(tmp, THIS);
-      for (i = len - 1; i>= 0; i-- )
-	{
-	  s->str[i] = mpz_get_ui(tmp) & 0xff;
-	  mpz_tdiv_q_2exp(tmp, tmp, 8);
-	}
-      assert(mpz_sgn(tmp) == 0);
-      mpz_clear(tmp);
-      s = end_shared_string(s);
-    }
-  else
-    error("invalid base.\n");
-  
+  {
+    if (sp[-args].type != T_INT)
+      error("Bad argument 1 for Mpz->digits().\n");
+    base = sp[-args].u.integer;
+  }
   pop_n_elems(args);
-  push_string(s);
+
+  push_string(low_get_digits(THIS, base));
 }
 
 static void mpzmod_size(INT32 args)
 {
   int base;
   if (!args)
+  {
     /* Default is number of bits */
     base = 2;
+  }
   else
-    {
-      if ((sp-args)->type != T_INT)
-	error("wrong type");
-      base = (sp-args)->u.integer;
-      if ((base != 256) && ((base < 2) || (base > 36)))
-	error("invalid base");
-    }
+  {
+    if (sp[-args].type != T_INT)
+      error("bad argument 1 for Mpz->size()\n");
+    base = sp[-args].u.integer;
+    if ((base != 256) && ((base < 2) || (base > 36)))
+      error("invalid base\n");
+  }
   pop_n_elems(args);
+
   if (base == 256)
     push_int((mpz_sizeinbase(THIS, 2) + 7) / 8);
   else
diff --git a/src/modules/gmpmod/testsuite.in b/src/modules/gmpmod/testsuite.in
index 18143ee0274cd5a3e4105db70ed65845beffce76..39fd5d4ac9bea8960b8526c428ff260a95f76f6a 100644
--- a/src/modules/gmpmod/testsuite.in
+++ b/src/modules/gmpmod/testsuite.in
@@ -5,6 +5,13 @@ cond( [[ master()->programs["/precompiled/mpz"] ]],
   test_true(programp(MPZ))
   test_false(clone(MPZ))
   test_do(destruct(clone(MPZ)))
+
+  test_eq(Mpz(10),10)
+  test_eq(Mpz("10"),10)
+  test_eq(Mpz(10.0),10)
+  test_eq(Mpz("10",8),8)
+  test_eq(Mpz("0",256),'0')
+
   test_eq(clone(MPZ,99)+1,100)
   test_eq(clone(MPZ,100)*10,1000)
   test_eq(clone(MPZ,"100")*10.0,1000)
@@ -36,13 +43,11 @@ cond( [[ master()->programs["/precompiled/mpz"] ]],
   define([[mpz_test_type1]],[[
     mpz_test_cmp($1,$2)
     mpz_test_cmp($1.0,$2)
-    mpz_test_cmp("$1",$2)
   ]])
 
   define([[mpz_test_type2]],[[
     mpz_test_type1($1,$2)
     mpz_test_type1($1,$2.0)
-    mpz_test_type1($1,"$2")
   ]])
 
   mpz_test_type2(1,2)