diff --git a/CHANGES b/CHANGES
index 78b8eae17aeae7d1218a1f60874ba57df88ec82a..db465b01007f5e8b668ca0437d2cfaf89decce78 100644
--- a/CHANGES
+++ b/CHANGES
@@ -96,6 +96,12 @@ o Web.Sass
 Bug fixes
 ---------
 
+o ADT.CritBit
+
+  - Due to an off-by-one error the last limb of bignums was never compared.
+    This resulted (sometimes) in unequal bignums comparing equal inside of
+    the tree.
+
 o Compiler
 
   - Improved variant robustness.
diff --git a/src/post_modules/CritBit/critbit/key_bignum.h b/src/post_modules/CritBit/critbit/key_bignum.h
index 5775ce5f247e1aa78283d6df8ddb407979a658f8..410675878b5edb8f118c631d05141b0840c10168 100644
--- a/src/post_modules/CritBit/critbit/key_bignum.h
+++ b/src/post_modules/CritBit/critbit/key_bignum.h
@@ -19,11 +19,13 @@ typedef mp_limb_t CB_NAME(char);
 #define cb_char CB_NAME(char)
 
 static CB_INLINE unsigned INT32 gclz(mp_limb_t a) {
-    if (sizeof(mp_limb_t) == 8) {
-	return clz64((unsigned INT64)a);
-    } else {
-	return clz32((unsigned INT32)a);
-    }
+#if GMP_NUMB_BITS == 64
+    return clz64((unsigned INT64)a);
+#elif GMP_NUMB_BITS == 32
+    return clz32((unsigned INT32)a);
+#else
+#error Only supports limb sizes of 32 or 64 bits.
+#endif
 }
 
 #define O2G(o) ((MP_INT*)(o->storage))
@@ -46,11 +48,9 @@ static CB_INLINE mp_limb_t CB_GET_CHAR(cb_string s, ptrdiff_t n) {
     MP_INT * i = O2G(s);
 
     n += abs(i->_mp_size);
-    if (n > 0) {
-	//fprintf(stderr, ">> %lld %lld\n", n, i->_mp_d[abs(n)]);
-	return i->_mp_d[abs(i->_mp_size)-n];
+    if (n >= 0) {
+        return i->_mp_d[abs(i->_mp_size) - 1 - n];
     } else {
-	//fprintf(stderr, "�� %lld %lld\n", n, i->_mp_d[abs(n)]);
 	return 0;
     }
 }
diff --git a/src/post_modules/CritBit/testsuite.in b/src/post_modules/CritBit/testsuite.in
index ce50314ec827c802649279613bd852fc93379c75..1d2a9dddac0399277faa95989f69b85c2c31a55a 100644
--- a/src/post_modules/CritBit/testsuite.in
+++ b/src/post_modules/CritBit/testsuite.in
@@ -200,6 +200,6 @@ test_tree(ADT.CritBit.IPv4Tree, [[mkmapping(map(enumerate(100)+enumerate(1000, -
 }), enumerate(2100))]], ADT.CritBit.sort_ipv4)
 test_tree(ADT.CritBit.FloatTree, [[mkmapping((array(float))(enumerate(100)+enumerate(1000, -19, 666)+enumerate(1000, Int.NATIVE_MAX/600, Int.NATIVE_MIN)), enumerate(2100))]], sort)
 test_tree(ADT.CritBit.DateTree, [[mkmapping(map(enumerate(2000, time()/3000, 1), Function.curry(Calendar.Second)("unix")), enumerate(2000))]], sort)
-
+test_tree(ADT.CritBit.BigNumTree, [[mkmapping(enumerate(10000, 2*Int.NATIVE_MAX, Int.NATIVE_MAX+1), enumerate(10000))]], sort)
 
 END_MARKER
diff --git a/src/post_modules/CritBit/tree_high.c b/src/post_modules/CritBit/tree_high.c
index c87676d6406f48b0201672f40e20d24986525573..648c7a8efa3877ed5a8e038786bbf6da2a7f2162 100644
--- a/src/post_modules/CritBit/tree_high.c
+++ b/src/post_modules/CritBit/tree_high.c
@@ -25,9 +25,9 @@ static inline void cb_debug_print_key(struct string_builder * buf, cb_key key) {
 #ifdef CB_PRINT_CHAR
 	CB_PRINT_CHAR(buf, key.str, i.chars);
 #else
-	string_builder_sprintf(buf, "(%d, %d) b: ", i.chars, CB_WIDTH(s));
+	string_builder_sprintf(buf, "(%d, %d) b: ", i.chars, CB_WIDTH(key.str));
 
-	for (i.bits = 0; i.bits < CB_WIDTH(s); i.bits++) {
+	for (i.bits = 0; i.bits < CB_WIDTH(key.str); i.bits++) {
 	    string_builder_sprintf(buf, "%d", CB_GET_BIT(key.str, i));
 	}
 	string_builder_putchar(buf, ' ');
@@ -53,7 +53,7 @@ static inline void cb_print_key(struct string_builder * buf, const cb_key key) {
     cb_size i;
 
     for (i.chars = 0; i.chars < key.len.chars; i.chars++) {
-	for (i.bits = 0; i.bits < CB_WIDTH(s); i.bits++) {
+	for (i.bits = 0; i.bits < CB_WIDTH(key.str); i.bits++) {
 	    string_builder_putchar(buf, CB_GET_BIT(key.str, i) ? '1' : '0');
 	}
     }