diff --git a/runtime.c b/runtime.c
index 93dd9d29..56e91c9e 100644
--- a/runtime.c
+++ b/runtime.c
@@ -269,6 +269,26 @@ static C_TLS int timezone;
 #define C_thread_id(x)   C_block_item((x), 14)
 
 
+#ifdef C_SIXTY_FOUR
+# define C_TYPE_HASH_SHIFT           48
+#else
+# define C_TYPE_HASH_SHIFT           16
+#endif
+
+/* A numeric type hash packs the type bits into the bottom 12 bits (regardless of immediate/block type). */
+/* NOTE: Only fixnum-immediates are currently distinguished - to make this more generic one would need to use one more test */
+#define C_type_hash(x)               (((x) & C_IMMEDIATE_MARK_BITS) ? ((x) & C_FIXNUM_BIT) : (C_header_bits(x) >> C_TYPE_HASH_SHIFT))
+/* For dyadic procedures (with two arguments), combine both type hashes */
+#define C_dyadic_hash(x, y)          ((x << 16) | y)
+
+/* We only care about numeric type hashes currently */
+#define C_FIXNUM_TYPE_HASH           C_FIXNUM_BIT
+#define C_FLONUM_TYPE_HASH           (C_FLONUM_TYPE >> C_TYPE_HASH_SHIFT)
+#define C_BIGNUM_TYPE_HASH           (C_BIGNUM_TYPE >> C_TYPE_HASH_SHIFT)
+#define C_RATNUM_TYPE_HASH           (C_RATNUM_TYPE >> C_TYPE_HASH_SHIFT)
+#define C_CPLXNUM_TYPE_HASH          (C_CPLXNUM_TYPE >> C_TYPE_HASH_SHIFT)
+
+
 /* Type definitions: */
 
 typedef C_regparm C_word C_fcall (*integer_plusmin_op) (C_word **ptr, C_word n, C_word x, C_word y);
@@ -5287,79 +5307,79 @@ C_word C_fcall C_a_i_smart_mpointer(C_word **ptr, int c, C_word x)
 
 C_regparm C_word C_fcall C_i_nanp(C_word x)
 {
-  if (x & C_FIXNUM_BIT) {
+  switch(C_type_hash(x)) {
+  case C_FIXNUM_TYPE_HASH:
+  case C_BIGNUM_TYPE_HASH:
+  case C_RATNUM_TYPE_HASH:
     return C_SCHEME_FALSE;
-  } else if (C_immediatep(x)) {
-    barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "nan?", x);
-  } else if (C_block_header(x) == C_FLONUM_TAG) {
+
+  case C_FLONUM_TYPE_HASH:
     return C_u_i_flonum_nanp(x);
-  } else if (C_truep(C_bignump(x))) {
-    return C_SCHEME_FALSE;
-  } else if (C_block_header(x) == C_RATNUM_TAG) {
-    return C_SCHEME_FALSE;
-  } else if (C_block_header(x) == C_CPLXNUM_TAG) {
+
+  case C_CPLXNUM_TYPE_HASH:
     return C_mk_bool(C_truep(C_i_nanp(C_u_i_cplxnum_real(x))) ||
 		     C_truep(C_i_nanp(C_u_i_cplxnum_imag(x))));
-  } else {
+
+  default:
     barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "nan?", x);
   }
 }
 
 C_regparm C_word C_fcall C_i_finitep(C_word x)
 {
-  if (x & C_FIXNUM_BIT) {
+  switch(C_type_hash(x)) {
+  case C_FIXNUM_TYPE_HASH:
+  case C_BIGNUM_TYPE_HASH:
+  case C_RATNUM_TYPE_HASH:
     return C_SCHEME_TRUE;
-  } else if (C_immediatep(x)) {
-    barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "finite?", x);
-  } else if (C_block_header(x) == C_FLONUM_TAG) {
+
+  case C_FLONUM_TYPE_HASH:
     return C_u_i_flonum_finitep(x);
-  } else if (C_truep(C_bignump(x))) {
-    return C_SCHEME_TRUE;
-  } else if (C_block_header(x) == C_RATNUM_TAG) {
-    return C_SCHEME_TRUE;
-  } else if (C_block_header(x) == C_CPLXNUM_TAG) {
+
+  case C_CPLXNUM_TYPE_HASH:
     return C_and(C_i_finitep(C_u_i_cplxnum_real(x)),
 		 C_i_finitep(C_u_i_cplxnum_imag(x)));
-  } else {
+
+  default:
     barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "finite?", x);
   }
 }
 
 C_regparm C_word C_fcall C_i_infinitep(C_word x)
 {
-  if (x & C_FIXNUM_BIT) {
+  switch(C_type_hash(x)) {
+  case C_FIXNUM_TYPE_HASH:
+  case C_BIGNUM_TYPE_HASH:
+  case C_RATNUM_TYPE_HASH:
     return C_SCHEME_FALSE;
-  } else if (C_immediatep(x)) {
-    barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "infinite?", x);
-  } else if (C_block_header(x) == C_FLONUM_TAG) {
+
+  case C_FLONUM_TYPE_HASH:
     return C_u_i_flonum_infinitep(x);
-  } else if (C_truep(C_bignump(x))) {
-    return C_SCHEME_FALSE;
-  } else if (C_block_header(x) == C_RATNUM_TAG) {
-    return C_SCHEME_FALSE;
-  } else if (C_block_header(x) == C_CPLXNUM_TAG) {
+
+  case C_CPLXNUM_TYPE_HASH:
     return C_mk_bool(C_truep(C_i_infinitep(C_u_i_cplxnum_real(x))) ||
                      C_truep(C_i_infinitep(C_u_i_cplxnum_imag(x))));
-  } else {
+
+  default:
     barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "infinite?", x);
   }
 }
 
 C_regparm C_word C_fcall C_i_exactp(C_word x)
 {
-  if (x & C_FIXNUM_BIT) {
+  switch(C_type_hash(x)) {
+  case C_FIXNUM_TYPE_HASH:
+  case C_BIGNUM_TYPE_HASH:
+  case C_RATNUM_TYPE_HASH:
     return C_SCHEME_TRUE;
-  } else if (C_immediatep(x)) {
-    barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "exact?", x);
-  } else if (C_block_header(x) == C_FLONUM_TAG) {
+
+  case C_FLONUM_TYPE_HASH:
     return C_SCHEME_FALSE;
-  } else if (C_truep(C_bignump(x))) {
-    return C_SCHEME_TRUE;
-  } else if (C_block_header(x) == C_RATNUM_TAG) {
-    return C_SCHEME_TRUE;
-  } else if (C_block_header(x) == C_CPLXNUM_TAG) {
+
+  case C_CPLXNUM_TYPE_HASH:
     return C_i_exactp(C_u_i_cplxnum_real(x)); /* Exactness of i and r matches */
-  } else {
+
+  default:
     barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "exact?", x);
   }
 }
@@ -5367,19 +5387,19 @@ C_regparm C_word C_fcall C_i_exactp(C_word x)
 
 C_regparm C_word C_fcall C_i_inexactp(C_word x)
 {
-  if (x & C_FIXNUM_BIT) {
+  switch(C_type_hash(x)) {
+  case C_FIXNUM_TYPE_HASH:
+  case C_BIGNUM_TYPE_HASH:
+  case C_RATNUM_TYPE_HASH:
     return C_SCHEME_FALSE;
-  } else if (C_immediatep(x)) {
-    barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "inexact?", x);
-  } else if (C_block_header(x) == C_FLONUM_TAG) {
+
+  case C_FLONUM_TYPE_HASH:
     return C_SCHEME_TRUE;
-  } else if (C_truep(C_bignump(x))) {
-    return C_SCHEME_FALSE;
-  } else if (C_block_header(x) == C_RATNUM_TAG) {
-    return C_SCHEME_FALSE;
-  } else if (C_block_header(x) == C_CPLXNUM_TAG) {
+
+  case C_CPLXNUM_TYPE_HASH:
     return C_i_inexactp(C_u_i_cplxnum_real(x)); /* Exactness of i and r matches */
-  } else {
+
+  default:
     barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "inexact?", x);
   }
 }
@@ -5387,17 +5407,19 @@ C_regparm C_word C_fcall C_i_inexactp(C_word x)
 
 C_regparm C_word C_fcall C_i_zerop(C_word x)
 {
-  if (x & C_FIXNUM_BIT) {
+  switch(C_type_hash(x)) {
+  case C_FIXNUM_TYPE_HASH:
     return C_mk_bool(x == C_fix(0));
-  } else if (C_immediatep(x)) {
-    barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "zero?", x);
-  } else if (C_block_header(x) == C_FLONUM_TAG) {
+
+  case C_FLONUM_TYPE_HASH:
     return C_mk_bool(C_flonum_magnitude(x) == 0.0);
-  } else if (C_block_header(x) == C_BIGNUM_TAG ||
-             C_block_header(x) == C_RATNUM_TAG ||
-             C_block_header(x) == C_CPLXNUM_TAG) {
+
+  case C_BIGNUM_TYPE_HASH:
+  case C_RATNUM_TYPE_HASH:
+  case C_CPLXNUM_TYPE_HASH:
     return C_SCHEME_FALSE;
-  } else {
+
+  default:
     barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "zero?", x);
   }
 }
@@ -5414,20 +5436,25 @@ C_regparm C_word C_fcall C_u_i_zerop(C_word x)
 
 C_regparm C_word C_fcall C_i_positivep(C_word x)
 {
-  if (x & C_FIXNUM_BIT)
+  switch(C_type_hash(x)) {
+  case C_FIXNUM_TYPE_HASH:
     return C_i_fixnum_positivep(x);
-  else if (C_immediatep(x))
-    barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "positive?", x);
-  else if (C_block_header(x) == C_FLONUM_TAG)
+
+  case C_FLONUM_TYPE_HASH:
     return C_mk_bool(C_flonum_magnitude(x) > 0.0);
-  else if (C_truep(C_bignump(x)))
+
+  case C_BIGNUM_TYPE_HASH:
     return C_mk_nbool(C_bignum_negativep(x));
-  else if (C_block_header(x) == C_RATNUM_TAG)
+
+  case C_RATNUM_TYPE_HASH:
     return C_i_integer_positivep(C_u_i_ratnum_num(x));
-  else if (C_block_header(x) == C_CPLXNUM_TAG)
+
+  case C_CPLXNUM_TYPE_HASH:
     barf(C_BAD_ARGUMENT_TYPE_NO_REAL_ERROR, "positive?", x);
-  else
+
+  default:
     barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "positive?", x);
+  }
 }
 
 C_regparm C_word C_fcall C_i_integer_positivep(C_word x)
@@ -5438,20 +5465,25 @@ C_regparm C_word C_fcall C_i_integer_positivep(C_word x)
 
 C_regparm C_word C_fcall C_i_negativep(C_word x)
 {
-  if (x & C_FIXNUM_BIT)
+  switch(C_type_hash(x)) {
+  case C_FIXNUM_TYPE_HASH:
     return C_i_fixnum_negativep(x);
-  else if (C_immediatep(x))
-    barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "negative?", x);
-  else if (C_block_header(x) == C_FLONUM_TAG)
+
+  case C_FLONUM_TYPE_HASH:
     return C_mk_bool(C_flonum_magnitude(x) < 0.0);
-  else if (C_truep(C_bignump(x)))
+
+  case C_BIGNUM_TYPE_HASH:
     return C_mk_bool(C_bignum_negativep(x));
-  else if (C_block_header(x) == C_RATNUM_TAG)
+
+  case C_RATNUM_TYPE_HASH:
     return C_i_integer_negativep(C_u_i_ratnum_num(x));
-  else if (C_block_header(x) == C_CPLXNUM_TAG)
+
+  case C_CPLXNUM_TYPE_HASH:
     barf(C_BAD_ARGUMENT_TYPE_NO_REAL_ERROR, "negative?", x);
-  else
+
+  default:
     barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "negative?", x);
+  }
 }
 
 
@@ -5464,20 +5496,24 @@ C_regparm C_word C_fcall C_i_integer_negativep(C_word x)
 
 C_regparm C_word C_fcall C_i_evenp(C_word x)
 {
-  if(x & C_FIXNUM_BIT) {
+  switch(C_type_hash(x)) {
+  case C_FIXNUM_TYPE_HASH:
     return C_i_fixnumevenp(x);
-  } else if(C_immediatep(x)) {
-    barf(C_BAD_ARGUMENT_TYPE_NO_INTEGER_ERROR, "even?", x);
-  } else if (C_block_header(x) == C_FLONUM_TAG) {
+
+  case C_FLONUM_TYPE_HASH:
+  {
     double val, dummy;
     val = C_flonum_magnitude(x);
     if(C_isnan(val) || C_isinf(val) || C_modf(val, &dummy) != 0.0)
       barf(C_BAD_ARGUMENT_TYPE_NO_INTEGER_ERROR, "even?", x);
     else
       return C_mk_bool(fmod(val, 2.0) == 0.0);
-  } else if (C_truep(C_bignump(x))) {
+  }
+
+  case C_BIGNUM_TYPE_HASH:
     return C_mk_nbool(C_bignum_digits(x)[0] & 1);
-  } else { /* No need to try extended number */
+
+  default:
     barf(C_BAD_ARGUMENT_TYPE_NO_INTEGER_ERROR, "even?", x);
   }
 }
@@ -5491,20 +5527,24 @@ C_regparm C_word C_fcall C_i_integer_evenp(C_word x)
 
 C_regparm C_word C_fcall C_i_oddp(C_word x)
 {
-  if(x & C_FIXNUM_BIT) {
+  switch(C_type_hash(x)) {
+  case C_FIXNUM_TYPE_HASH:
     return C_i_fixnumoddp(x);
-  } else if(C_immediatep(x)) {
-    barf(C_BAD_ARGUMENT_TYPE_NO_INTEGER_ERROR, "odd?", x);
-  } else if(C_block_header(x) == C_FLONUM_TAG) {
+
+  case C_FLONUM_TYPE_HASH:
+  {
     double val, dummy;
     val = C_flonum_magnitude(x);
     if(C_isnan(val) || C_isinf(val) || C_modf(val, &dummy) != 0.0)
       barf(C_BAD_ARGUMENT_TYPE_NO_INTEGER_ERROR, "odd?", x);
     else
       return C_mk_bool(fmod(val, 2.0) != 0.0);
-  } else if (C_truep(C_bignump(x))) {
+  }
+
+  case C_BIGNUM_TYPE_HASH:
     return C_mk_bool(C_bignum_digits(x)[0] & 1);
-  } else {
+
+  default:
     barf(C_BAD_ARGUMENT_TYPE_NO_INTEGER_ERROR, "odd?", x);
   }
 }
@@ -6400,20 +6440,24 @@ C_regparm C_word C_fcall C_i_f64vector_set(C_word v, C_word i, C_word x)
 C_regparm C_word C_fcall
 C_s_a_i_abs(C_word **ptr, C_word n, C_word x)
 {
-  if (x & C_FIXNUM_BIT) {
+  switch(C_type_hash(x)) {
+  case C_FIXNUM_TYPE_HASH:
     return C_a_i_fixnum_abs(ptr, 1, x);
-  } else if (C_immediatep(x)) {
-    barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "abs", x);
-  } else if (C_block_header(x) == C_FLONUM_TAG) {
+
+  case C_FLONUM_TYPE_HASH:
     return C_a_i_flonum_abs(ptr, 1, x);
-  } else if (C_truep(C_bignump(x))) {
+
+  case C_BIGNUM_TYPE_HASH:
     return C_s_a_u_i_integer_abs(ptr, 1, x);
-  } else if (C_block_header(x) == C_RATNUM_TAG) {
+
+  case C_RATNUM_TYPE_HASH:
     return C_ratnum(ptr, C_s_a_u_i_integer_abs(ptr, 1, C_u_i_ratnum_num(x)),
                     C_u_i_ratnum_denom(x));
-  } else if (C_block_header(x) == C_CPLXNUM_TAG) {
+
+  case C_CPLXNUM_TYPE_HASH:
     barf(C_BAD_ARGUMENT_TYPE_COMPLEX_ABS, "abs", x);
-  } else {
+
+  default:
     barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "abs", x);
   }
 }
@@ -6427,17 +6471,25 @@ void C_ccall C_signum(C_word c, C_word *av)
   x = av[ 2 ];
   y = av[ 3 ];
 
-  if (x & C_FIXNUM_BIT) {
+  switch(C_type_hash(x)) {
+  case C_FIXNUM_TYPE_HASH:
     C_kontinue(k, C_i_fixnum_signum(x));
-  } else if (C_immediatep(x)) {
-    barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "signum", x);
-  } else if (C_block_header(x) == C_FLONUM_TAG) {
+
+  case C_FLONUM_TYPE_HASH:
+  {
     C_word *a = C_alloc(C_SIZEOF_FLONUM);
     C_kontinue(k, C_a_u_i_flonum_signum(&a, 1, x));
-  } else if (C_truep(C_bignump(x))) {
+  }
+  
+  case C_BIGNUM_TYPE_HASH:
     C_kontinue(k, C_bignum_negativep(x) ? C_fix(-1) : C_fix(1));
-  } else {
+
+  case C_RATNUM_TYPE_HASH:
+  case C_CPLXNUM_TYPE_HASH:
     try_extended_number("##sys#extended-signum", 2, k, x);
+
+  default:
+    barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "signum", x);
   }
 }
 
@@ -6449,21 +6501,25 @@ void C_ccall C_signum(C_word c, C_word *av)
 C_regparm C_word C_fcall
 C_s_a_i_negate(C_word **ptr, C_word n, C_word x)
 {
-  if (x & C_FIXNUM_BIT) {
+  switch(C_type_hash(x)) {
+  case C_FIXNUM_TYPE_HASH:
     return C_a_i_fixnum_negate(ptr, 1, x);
-  } else if (C_immediatep(x)) {
-    barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "-", x);
-  } else if (C_block_header(x) == C_FLONUM_TAG) {
+
+  case C_FLONUM_TYPE_HASH:
     return C_a_i_flonum_negate(ptr, 1, x);
-  } else if (C_truep(C_bignump(x))) {
+
+  case C_BIGNUM_TYPE_HASH:
     return C_s_a_u_i_integer_negate(ptr, 1, x);
-  } else if (C_block_header(x) == C_RATNUM_TAG) {
+
+  case C_RATNUM_TYPE_HASH:
     return C_ratnum(ptr, C_s_a_u_i_integer_negate(ptr, 1, C_u_i_ratnum_num(x)),
                     C_u_i_ratnum_denom(x));
-  } else if (C_block_header(x) == C_CPLXNUM_TAG) {
+
+  case C_CPLXNUM_TYPE_HASH:
     return C_cplxnum(ptr, C_s_a_i_negate(ptr, 1, C_u_i_cplxnum_real(x)),
                      C_s_a_i_negate(ptr, 1, C_u_i_cplxnum_imag(x)));
-  } else {
+
+  default:
     barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "-", x);
   }
 }
@@ -7987,88 +8043,95 @@ cplx_times(C_word **ptr, C_word rx, C_word ix, C_word ry, C_word iy)
 C_regparm C_word C_fcall
 C_s_a_i_times(C_word **ptr, C_word n, C_word x, C_word y)
 {
-  if (x & C_FIXNUM_BIT) {
-    if (y & C_FIXNUM_BIT) {
-      return C_a_i_fixnum_times(ptr, 2, x, y);
-    } else if (C_immediatep(y)) {
-      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "*", y);
-    } else if (C_block_header(y) == C_FLONUM_TAG) {
-      return C_flonum(ptr, (double)C_unfix(x) * C_flonum_magnitude(y));
-    } else if (C_truep(C_bignump(y))) {
-      return C_s_a_u_i_integer_times(ptr, 2, x, y);
-    } else if (C_block_header(y) == C_RATNUM_TAG) {
-      return rat_times_integer(ptr, y, x);
-    } else if (C_block_header(y) == C_CPLXNUM_TAG) {
-      return cplx_times(ptr, x, C_fix(0),
-                        C_u_i_cplxnum_real(y), C_u_i_cplxnum_imag(y));
-    } else {
-      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "*", y);
-    }
-  } else if (C_immediatep(x)) {
-    barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "*", x);
-  } else if (C_block_header(x) == C_FLONUM_TAG) {
-    if (y & C_FIXNUM_BIT) {
-      return C_flonum(ptr, C_flonum_magnitude(x) * (double)C_unfix(y));
-    } else if (C_immediatep(y)) {
-      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "*", y);
-    } else if (C_block_header(y) == C_FLONUM_TAG) {
-      return C_a_i_flonum_times(ptr, 2, x, y);
-    } else if (C_truep(C_bignump(y))) {
-      return C_flonum(ptr, C_flonum_magnitude(x) * C_bignum_to_double(y));
-    } else if (C_block_header(y) == C_RATNUM_TAG) {
-      return C_s_a_i_times(ptr, 2, x, C_a_i_exact_to_inexact(ptr, 1, y));
-    } else if (C_block_header(y) == C_CPLXNUM_TAG) {
-      C_word ab[C_SIZEOF_FLONUM], *a = ab;
-      return cplx_times(ptr, x, C_flonum(&a, 0.0),
-                        C_u_i_cplxnum_real(y), C_u_i_cplxnum_imag(y));
-    } else {
-      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "*", y);
-    }
-  } else if (C_truep(C_bignump(x))) {
-    if (y & C_FIXNUM_BIT) {
-      return C_s_a_u_i_integer_times(ptr, 2, x, y);
-    } else if (C_immediatep(y)) {
+  switch(C_dyadic_hash(C_type_hash(x), C_type_hash(y))) {
+  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
+    return C_a_i_fixnum_times(ptr, 2, x, y);
+
+  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
+    return C_flonum(ptr, (double)C_unfix(x) * C_flonum_magnitude(y));
+
+  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
+    return C_s_a_u_i_integer_times(ptr, 2, x, y);
+
+  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
+    return rat_times_integer(ptr, y, x);
+
+  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
+    return cplx_times(ptr, x, C_fix(0),
+                      C_u_i_cplxnum_real(y), C_u_i_cplxnum_imag(y));
+
+
+  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
+    return C_flonum(ptr, C_flonum_magnitude(x) * (double)C_unfix(y));
+
+  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
+    return C_a_i_flonum_times(ptr, 2, x, y);
+
+  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
+    return C_flonum(ptr, C_flonum_magnitude(x) * C_bignum_to_double(y));
+
+  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
+    return C_s_a_i_times(ptr, 2, x, C_a_i_exact_to_inexact(ptr, 1, y));
+
+  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
+  {
+    C_word ab[C_SIZEOF_FLONUM], *a = ab;
+    return cplx_times(ptr, x, C_flonum(&a, 0.0),
+                      C_u_i_cplxnum_real(y), C_u_i_cplxnum_imag(y));
+  }
+
+  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
+    return C_s_a_u_i_integer_times(ptr, 2, x, y);
+
+  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
+    return C_flonum(ptr, C_bignum_to_double(x) * C_flonum_magnitude(y));
+
+  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
+    return C_s_a_u_i_integer_times(ptr, 2, x, y);
+
+  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
+    return rat_times_integer(ptr, y, x);
+
+  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
+    return cplx_times(ptr, x, C_fix(0),
+                      C_u_i_cplxnum_real(y), C_u_i_cplxnum_imag(y));
+
+
+  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
+    return rat_times_integer(ptr, x, y);
+
+  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
+    return C_s_a_i_times(ptr, 2, C_a_i_exact_to_inexact(ptr, 1, x), y);
+
+  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
+    return rat_times_integer(ptr, x, y);
+
+  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
+    return rat_times_rat(ptr, x, y);
+
+  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
+    return cplx_times(ptr, x, C_fix(0),
+                      C_u_i_cplxnum_real(y), C_u_i_cplxnum_imag(y));
+
+  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
+    return cplx_times(ptr, C_u_i_cplxnum_real(x), C_u_i_cplxnum_imag(x),
+                      C_u_i_cplxnum_real(y), C_u_i_cplxnum_imag(y));
+
+  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
+  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
+  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
+  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
+  {
+    C_word ab[C_SIZEOF_FLONUM], *a = ab, yi;
+    yi = C_truep(C_i_flonump(y)) ? C_flonum(&a,0) : C_fix(0);
+    return cplx_times(ptr, C_u_i_ratnum_num(x), C_u_i_ratnum_denom(x), y, yi);
+  }
+
+  default:
+    if (!C_truep(C_i_numberp(x)))
       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "*", x);
-    } else if (C_block_header(y) == C_FLONUM_TAG) {
-      return C_flonum(ptr, C_bignum_to_double(x) * C_flonum_magnitude(y));
-    } else if (C_truep(C_bignump(y))) {
-      return C_s_a_u_i_integer_times(ptr, 2, x, y);
-    } else if (C_block_header(y) == C_RATNUM_TAG) {
-      return rat_times_integer(ptr, y, x);
-    } else if (C_block_header(y) == C_CPLXNUM_TAG) {
-      return cplx_times(ptr, x, C_fix(0),
-                        C_u_i_cplxnum_real(y), C_u_i_cplxnum_imag(y));
-    } else {
-      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "*", y);
-    }
-  } else if (C_block_header(x) == C_RATNUM_TAG) {
-    if (y & C_FIXNUM_BIT) {
-      return rat_times_integer(ptr, x, y);
-    } else if (C_immediatep(y)) {
-      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "*", y);
-    } else if (C_block_header(y) == C_FLONUM_TAG) {
-      return C_s_a_i_times(ptr, 2, C_a_i_exact_to_inexact(ptr, 1, x), y);
-    } else if (C_truep(C_bignump(y))) {
-      return rat_times_integer(ptr, x, y);
-    } else if (C_block_header(y) == C_RATNUM_TAG) {
-        return rat_times_rat(ptr, x, y);
-    } else if (C_block_header(y) == C_CPLXNUM_TAG) {
-      return cplx_times(ptr, x, C_fix(0),
-                        C_u_i_cplxnum_real(y), C_u_i_cplxnum_imag(y));
-    } else {
+    else
       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "*", y);
-    }
-  } else if (C_block_header(x) == C_CPLXNUM_TAG) {
-    if (!C_immediatep(y) && C_block_header(y) == C_CPLXNUM_TAG) {
-      return cplx_times(ptr, C_u_i_cplxnum_real(x), C_u_i_cplxnum_imag(x),
-                        C_u_i_cplxnum_real(y), C_u_i_cplxnum_imag(y));
-    } else {
-      C_word ab[C_SIZEOF_FLONUM], *a = ab, yi;
-      yi = C_truep(C_i_flonump(y)) ? C_flonum(&a,0) : C_fix(0);
-      return cplx_times(ptr, C_u_i_ratnum_num(x), C_u_i_ratnum_denom(x), y, yi);
-    }
-  } else {
-    barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "*", x);
   }
 }
 
@@ -8382,104 +8445,115 @@ static C_word rat_plusmin_rat(C_word **ptr, C_word x, C_word y, integer_plusmin_
 C_regparm C_word C_fcall
 C_s_a_i_plus(C_word **ptr, C_word n, C_word x, C_word y)
 {
-  if (x & C_FIXNUM_BIT) {
-    if (y & C_FIXNUM_BIT) {
-      return C_a_i_fixnum_plus(ptr, 2, x, y);
-    } else if (C_immediatep(y)) {
-      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "+", y);
-    } else if (C_block_header(y) == C_FLONUM_TAG) {
-      return C_flonum(ptr, (double)C_unfix(x) + C_flonum_magnitude(y));
-    } else if (C_truep(C_bignump(y))) {
-      return C_s_a_u_i_integer_plus(ptr, 2, x, y);
-    } else if (C_block_header(y) == C_RATNUM_TAG) {
-      return rat_plusmin_integer(ptr, y, x, C_s_a_u_i_integer_plus);
-    } else if (C_block_header(y) == C_CPLXNUM_TAG) {
-      C_word real_sum = C_s_a_i_plus(ptr, 2, x, C_u_i_cplxnum_real(y)),
-             imag = C_u_i_cplxnum_imag(y);
-      if (C_truep(C_u_i_inexactp(real_sum)))
-        imag = C_a_i_exact_to_inexact(ptr, 1, imag);
-      return C_cplxnum(ptr, real_sum, imag);
-    } else {
-      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "+", y);
-    }
-  } else if (C_immediatep(x)) {
-    barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "+", x);
-  } else if (C_block_header(x) == C_FLONUM_TAG) {
-    if (y & C_FIXNUM_BIT) {
-      return C_flonum(ptr, C_flonum_magnitude(x) + (double)C_unfix(y));
-    } else if (C_immediatep(y)) {
-      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "+", y);
-    } else if (C_block_header(y) == C_FLONUM_TAG) {
-      return C_a_i_flonum_plus(ptr, 2, x, y);
-    } else if (C_truep(C_bignump(y))) {
-      return C_flonum(ptr, C_flonum_magnitude(x)+C_bignum_to_double(y));
-    } else if (C_block_header(y) == C_RATNUM_TAG) {
-      return C_s_a_i_plus(ptr, 2, x, C_a_i_exact_to_inexact(ptr, 1, y));
-    } else if (C_block_header(y) == C_CPLXNUM_TAG) {
-      C_word real_sum = C_s_a_i_plus(ptr, 2, x, C_u_i_cplxnum_real(y)),
-             imag = C_u_i_cplxnum_imag(y);
-      if (C_truep(C_u_i_inexactp(real_sum)))
-        imag = C_a_i_exact_to_inexact(ptr, 1, imag);
-      return C_cplxnum(ptr, real_sum, imag);
-    } else {
-      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "+", y);
-    }
-  } else if (C_truep(C_bignump(x))) {
-    if (y & C_FIXNUM_BIT) {
-      return C_s_a_u_i_integer_plus(ptr, 2, x, y);
-    } else if (C_immediatep(y)) {
-      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "+", y);
-    } else if (C_block_header(y) == C_FLONUM_TAG) {
-      return C_flonum(ptr, C_bignum_to_double(x)+C_flonum_magnitude(y));
-    } else if (C_truep(C_bignump(y))) {
-      return C_s_a_u_i_integer_plus(ptr, 2, x, y);
-    } else if (C_block_header(y) == C_RATNUM_TAG) {
-      return rat_plusmin_integer(ptr, y, x, C_s_a_u_i_integer_plus);
-    } else if (C_block_header(y) == C_CPLXNUM_TAG) {
-      C_word real_sum = C_s_a_i_plus(ptr, 2, x, C_u_i_cplxnum_real(y)),
-             imag = C_u_i_cplxnum_imag(y);
-      if (C_truep(C_u_i_inexactp(real_sum)))
-        imag = C_a_i_exact_to_inexact(ptr, 1, imag);
-      return C_cplxnum(ptr, real_sum, imag);
-    } else {
-      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "+", y);
-    }
-  } else if (C_block_header(x) == C_RATNUM_TAG) {
-    if (y & C_FIXNUM_BIT) {
-      return rat_plusmin_integer(ptr, x, y, C_s_a_u_i_integer_plus);
-    } else if (C_immediatep(y)) {
-      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "+", y);
-    } else if (C_block_header(y) == C_FLONUM_TAG) {
-      return C_s_a_i_plus(ptr, 2, C_a_i_exact_to_inexact(ptr, 1, x), y);
-    } else if (C_truep(C_bignump(y))) {
-      return rat_plusmin_integer(ptr, x, y, C_s_a_u_i_integer_plus);
-    } else if (C_block_header(y) == C_RATNUM_TAG) {
-      return rat_plusmin_rat(ptr, x, y, C_s_a_u_i_integer_plus);
-    } else if (C_block_header(y) == C_CPLXNUM_TAG) {
-      C_word real_sum = C_s_a_i_plus(ptr, 2, x, C_u_i_cplxnum_real(y)),
-             imag = C_u_i_cplxnum_imag(y);
-      if (C_truep(C_u_i_inexactp(real_sum)))
-        imag = C_a_i_exact_to_inexact(ptr, 1, imag);
-      return C_cplxnum(ptr, real_sum, imag);
-    } else {
-      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "+", y);
-    }
-  } else if (C_block_header(x) == C_CPLXNUM_TAG) {
-    if (!C_immediatep(y) && C_block_header(y) == C_CPLXNUM_TAG) {
+  switch(C_dyadic_hash(C_type_hash(x), C_type_hash(y))) {
+  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
+    return C_a_i_fixnum_plus(ptr, 2, x, y);
+
+  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
+    return C_flonum(ptr, (double)C_unfix(x) + C_flonum_magnitude(y));
+
+  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
+    return C_s_a_u_i_integer_plus(ptr, 2, x, y);
+
+  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
+    return rat_plusmin_integer(ptr, y, x, C_s_a_u_i_integer_plus);
+
+  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
+  {
+    C_word real_sum = C_s_a_i_plus(ptr, 2, x, C_u_i_cplxnum_real(y)),
+      imag = C_u_i_cplxnum_imag(y);
+    if (C_truep(C_u_i_inexactp(real_sum)))
+      imag = C_a_i_exact_to_inexact(ptr, 1, imag);
+    return C_cplxnum(ptr, real_sum, imag);
+  }
+
+  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
+    return C_flonum(ptr, C_flonum_magnitude(x) + (double)C_unfix(y));
+
+  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
+    return C_a_i_flonum_plus(ptr, 2, x, y);
+
+  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
+    return C_flonum(ptr, C_flonum_magnitude(x)+C_bignum_to_double(y));
+
+  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
+    return C_s_a_i_plus(ptr, 2, x, C_a_i_exact_to_inexact(ptr, 1, y));
+
+  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
+  {
+    C_word real_sum = C_s_a_i_plus(ptr, 2, x, C_u_i_cplxnum_real(y)),
+      imag = C_u_i_cplxnum_imag(y);
+    if (C_truep(C_u_i_inexactp(real_sum)))
+      imag = C_a_i_exact_to_inexact(ptr, 1, imag);
+    return C_cplxnum(ptr, real_sum, imag);
+  }
+
+  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
+    return C_s_a_u_i_integer_plus(ptr, 2, x, y);
+
+  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
+    return C_flonum(ptr, C_bignum_to_double(x)+C_flonum_magnitude(y));
+
+  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
+    return C_s_a_u_i_integer_plus(ptr, 2, x, y);
+
+  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
+    return rat_plusmin_integer(ptr, y, x, C_s_a_u_i_integer_plus);
+
+  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
+  {
+    C_word real_sum = C_s_a_i_plus(ptr, 2, x, C_u_i_cplxnum_real(y)),
+      imag = C_u_i_cplxnum_imag(y);
+    if (C_truep(C_u_i_inexactp(real_sum)))
+      imag = C_a_i_exact_to_inexact(ptr, 1, imag);
+    return C_cplxnum(ptr, real_sum, imag);
+  }
+      
+  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
+  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
+    return rat_plusmin_integer(ptr, x, y, C_s_a_u_i_integer_plus);
+
+  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
+    return C_s_a_i_plus(ptr, 2, C_a_i_exact_to_inexact(ptr, 1, x), y);
+
+  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
+    return rat_plusmin_rat(ptr, x, y, C_s_a_u_i_integer_plus);
+
+  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
+  {
+    C_word real_sum = C_s_a_i_plus(ptr, 2, x, C_u_i_cplxnum_real(y)),
+      imag = C_u_i_cplxnum_imag(y);
+    if (C_truep(C_u_i_inexactp(real_sum)))
+      imag = C_a_i_exact_to_inexact(ptr, 1, imag);
+    return C_cplxnum(ptr, real_sum, imag);
+  }
+
+  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
+  {
       C_word real_sum, imag_sum;
       real_sum = C_s_a_i_plus(ptr, 2, C_u_i_cplxnum_real(x), C_u_i_cplxnum_real(y));
       imag_sum = C_s_a_i_plus(ptr, 2, C_u_i_cplxnum_imag(x), C_u_i_cplxnum_imag(y));
       if (C_truep(C_u_i_zerop2(imag_sum))) return real_sum;
       else return C_cplxnum(ptr, real_sum, imag_sum);
-    } else {
-      C_word real_sum = C_s_a_i_plus(ptr, 2, C_u_i_cplxnum_real(x), y),
-             imag = C_u_i_cplxnum_imag(x);
-      if (C_truep(C_u_i_inexactp(real_sum)))
-        imag = C_a_i_exact_to_inexact(ptr, 1, imag);
-      return C_cplxnum(ptr, real_sum, imag);
-    }
-  } else {
-    barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "+", x);
+  }
+
+  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
+  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
+  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
+  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
+  {
+    C_word real_sum = C_s_a_i_plus(ptr, 2, C_u_i_cplxnum_real(x), y),
+      imag = C_u_i_cplxnum_imag(x);
+    if (C_truep(C_u_i_inexactp(real_sum)))
+      imag = C_a_i_exact_to_inexact(ptr, 1, imag);
+    return C_cplxnum(ptr, real_sum, imag);
+  }
+
+  default:
+    if (!C_truep(C_i_numberp(x)))
+      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "+", x);
+    else
+      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "+", y);
   }
 }
 
@@ -8593,104 +8667,117 @@ static C_word bignum_minus_unsigned(C_word **ptr, C_word x, C_word y)
 C_regparm C_word C_fcall
 C_s_a_i_minus(C_word **ptr, C_word n, C_word x, C_word y)
 {
-  if (x & C_FIXNUM_BIT) {
-    if (y & C_FIXNUM_BIT) {
-      return C_a_i_fixnum_difference(ptr, 2, x, y);
-    } else if (C_immediatep(y)) {
-      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "-", y);
-    } else if (C_block_header(y) == C_FLONUM_TAG) {
-      return C_flonum(ptr, (double)C_unfix(x) - C_flonum_magnitude(y));
-    } else if (C_truep(C_bignump(y))) {
-      return C_s_a_u_i_integer_minus(ptr, 2, x, y);
-    } else if (C_block_header(y) == C_RATNUM_TAG) {
-      return integer_minus_rat(ptr, x, y);
-    } else if (C_block_header(y) == C_CPLXNUM_TAG) {
-      C_word real_diff = C_s_a_i_minus(ptr, 2, x, C_u_i_cplxnum_real(y)),
-             imag = C_s_a_i_negate(ptr, 1, C_u_i_cplxnum_imag(y));
-      if (C_truep(C_u_i_inexactp(real_diff)))
-        imag = C_a_i_exact_to_inexact(ptr, 1, imag);
-      return C_cplxnum(ptr, real_diff, imag);
-    } else {
-      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "-", y);
-    }
-  } else if (C_immediatep(x)) {
-    barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "-", x);
-  } else if (C_block_header(x) == C_FLONUM_TAG) {
-    if (y & C_FIXNUM_BIT) {
-      return C_flonum(ptr, C_flonum_magnitude(x) - (double)C_unfix(y));
-    } else if (C_immediatep(y)) {
-      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "-", y);
-    } else if (C_block_header(y) == C_FLONUM_TAG) {
-      return C_a_i_flonum_difference(ptr, 2, x, y);
-    } else if (C_truep(C_bignump(y))) {
-      return C_flonum(ptr, C_flonum_magnitude(x)-C_bignum_to_double(y));
-    } else if (C_block_header(y) == C_RATNUM_TAG) {
-      return C_s_a_i_minus(ptr, 2, x, C_a_i_exact_to_inexact(ptr, 1, y));
-    } else if (C_block_header(y) == C_CPLXNUM_TAG) {
-      C_word real_diff = C_s_a_i_minus(ptr, 2, x, C_u_i_cplxnum_real(y)),
-             imag = C_s_a_i_negate(ptr, 1, C_u_i_cplxnum_imag(y));
-      if (C_truep(C_u_i_inexactp(real_diff)))
-        imag = C_a_i_exact_to_inexact(ptr, 1, imag);
-      return C_cplxnum(ptr, real_diff, imag);
-    } else {
-      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "-", y);
-    }
-  } else if (C_truep(C_bignump(x))) {
-    if (y & C_FIXNUM_BIT) {
-      return C_s_a_u_i_integer_minus(ptr, 2, x, y);
-    } else if (C_immediatep(y)) {
-      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "-", y);
-    } else if (C_block_header(y) == C_FLONUM_TAG) {
-      return C_flonum(ptr, C_bignum_to_double(x)-C_flonum_magnitude(y));
-    } else if (C_truep(C_bignump(y))) {
-      return C_s_a_u_i_integer_minus(ptr, 2, x, y);
-    } else if (C_block_header(y) == C_RATNUM_TAG) {
-      return integer_minus_rat(ptr, x, y);
-    } else if (C_block_header(y) == C_CPLXNUM_TAG) {
-      C_word real_diff = C_s_a_i_minus(ptr, 2, x, C_u_i_cplxnum_real(y)),
-             imag = C_s_a_i_negate(ptr, 1, C_u_i_cplxnum_imag(y));
-      if (C_truep(C_u_i_inexactp(real_diff)))
-        imag = C_a_i_exact_to_inexact(ptr, 1, imag);
-      return C_cplxnum(ptr, real_diff, imag);
-    } else {
-      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "-", y);
-    }
-  } else if (C_block_header(x) == C_RATNUM_TAG) {
-    if (y & C_FIXNUM_BIT) {
-      return rat_plusmin_integer(ptr, x, y, C_s_a_u_i_integer_minus);
-    } else if (C_immediatep(y)) {
-      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "-", y);
-    } else if (C_block_header(y) == C_FLONUM_TAG) {
-      return C_s_a_i_minus(ptr, 2, C_a_i_exact_to_inexact(ptr, 1, x), y);
-    } else if (C_truep(C_bignump(y))) {
-      return rat_plusmin_integer(ptr, x, y, C_s_a_u_i_integer_minus);
-    } else if (C_block_header(y) == C_RATNUM_TAG) {
-      return rat_plusmin_rat(ptr, x, y, C_s_a_u_i_integer_minus);
-    } else if (C_block_header(y) == C_CPLXNUM_TAG) {
-      C_word real_diff = C_s_a_i_minus(ptr, 2, x, C_u_i_cplxnum_real(y)),
-             imag = C_s_a_i_negate(ptr, 1, C_u_i_cplxnum_imag(y));
-      if (C_truep(C_u_i_inexactp(real_diff)))
-        imag = C_a_i_exact_to_inexact(ptr, 1, imag);
-      return C_cplxnum(ptr, real_diff, imag);
-    } else {
+  switch(C_dyadic_hash(C_type_hash(x), C_type_hash(y))) {
+  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
+    return C_a_i_fixnum_difference(ptr, 2, x, y);
+
+  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
+    return C_flonum(ptr, (double)C_unfix(x) - C_flonum_magnitude(y));
+
+  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
+    return C_s_a_u_i_integer_minus(ptr, 2, x, y);
+
+  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
+    return integer_minus_rat(ptr, x, y);
+
+  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
+  {
+    C_word real_diff = C_s_a_i_minus(ptr, 2, x, C_u_i_cplxnum_real(y)),
+      imag = C_s_a_i_negate(ptr, 1, C_u_i_cplxnum_imag(y));
+    if (C_truep(C_u_i_inexactp(real_diff)))
+      imag = C_a_i_exact_to_inexact(ptr, 1, imag);
+    return C_cplxnum(ptr, real_diff, imag);
+  }
+
+  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
+    return C_flonum(ptr, C_flonum_magnitude(x) - (double)C_unfix(y));
+
+  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
+    return C_a_i_flonum_difference(ptr, 2, x, y);
+
+  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
+    return C_flonum(ptr, C_flonum_magnitude(x)-C_bignum_to_double(y));
+
+  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
+    return C_s_a_i_minus(ptr, 2, x, C_a_i_exact_to_inexact(ptr, 1, y));
+
+  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
+  {
+    C_word real_diff = C_s_a_i_minus(ptr, 2, x, C_u_i_cplxnum_real(y)),
+      imag = C_s_a_i_negate(ptr, 1, C_u_i_cplxnum_imag(y));
+    if (C_truep(C_u_i_inexactp(real_diff)))
+      imag = C_a_i_exact_to_inexact(ptr, 1, imag);
+    return C_cplxnum(ptr, real_diff, imag);
+  }
+
+  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
+    return C_s_a_u_i_integer_minus(ptr, 2, x, y);
+
+  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
+    return C_flonum(ptr, C_bignum_to_double(x)-C_flonum_magnitude(y));
+
+  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
+    return C_s_a_u_i_integer_minus(ptr, 2, x, y);
+
+  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
+    return integer_minus_rat(ptr, x, y);
+
+  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
+  {
+    C_word real_diff = C_s_a_i_minus(ptr, 2, x, C_u_i_cplxnum_real(y)),
+      imag = C_s_a_i_negate(ptr, 1, C_u_i_cplxnum_imag(y));
+    if (C_truep(C_u_i_inexactp(real_diff)))
+      imag = C_a_i_exact_to_inexact(ptr, 1, imag);
+    return C_cplxnum(ptr, real_diff, imag);
+  }
+
+  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
+    return rat_plusmin_integer(ptr, x, y, C_s_a_u_i_integer_minus);
+
+  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
+    return C_s_a_i_minus(ptr, 2, C_a_i_exact_to_inexact(ptr, 1, x), y);
+
+  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
+    return rat_plusmin_integer(ptr, x, y, C_s_a_u_i_integer_minus);
+
+  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
+    return rat_plusmin_rat(ptr, x, y, C_s_a_u_i_integer_minus);
+
+  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
+  {
+    C_word real_diff = C_s_a_i_minus(ptr, 2, x, C_u_i_cplxnum_real(y)),
+      imag = C_s_a_i_negate(ptr, 1, C_u_i_cplxnum_imag(y));
+    if (C_truep(C_u_i_inexactp(real_diff)))
+      imag = C_a_i_exact_to_inexact(ptr, 1, imag);
+    return C_cplxnum(ptr, real_diff, imag);
+  }
+
+  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
+  {
+    C_word real_diff, imag_diff;
+    real_diff = C_s_a_i_minus(ptr,2,C_u_i_cplxnum_real(x),C_u_i_cplxnum_real(y));
+    imag_diff = C_s_a_i_minus(ptr,2,C_u_i_cplxnum_imag(x),C_u_i_cplxnum_imag(y));
+    if (C_truep(C_u_i_zerop2(imag_diff))) return real_diff;
+    else return C_cplxnum(ptr, real_diff, imag_diff);
+  }
+
+  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
+  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
+  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
+  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
+  {
+    C_word real_diff = C_s_a_i_minus(ptr, 2, C_u_i_cplxnum_real(x), y),
+      imag = C_u_i_cplxnum_imag(x);
+    if (C_truep(C_u_i_inexactp(real_diff)))
+      imag = C_a_i_exact_to_inexact(ptr, 1, imag);
+    return C_cplxnum(ptr, real_diff, imag);
+  }
+
+  default:
+    if (!C_truep(C_i_numberp(x)))
+      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "-", x);
+    else
       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "-", y);
-    }
-  } else if (C_block_header(x) == C_CPLXNUM_TAG) {
-    if (!C_immediatep(y) && C_block_header(y) == C_CPLXNUM_TAG) {
-      C_word real_diff, imag_diff;
-      real_diff = C_s_a_i_minus(ptr,2,C_u_i_cplxnum_real(x),C_u_i_cplxnum_real(y));
-      imag_diff = C_s_a_i_minus(ptr,2,C_u_i_cplxnum_imag(x),C_u_i_cplxnum_imag(y));
-      if (C_truep(C_u_i_zerop2(imag_diff))) return real_diff;
-      else return C_cplxnum(ptr, real_diff, imag_diff);
-    } else {
-      C_word real_diff = C_s_a_i_minus(ptr, 2, C_u_i_cplxnum_real(x), y),
-             imag = C_u_i_cplxnum_imag(x);
-      if (C_truep(C_u_i_inexactp(real_diff)))
-        imag = C_a_i_exact_to_inexact(ptr, 1, imag);
-      return C_cplxnum(ptr, real_diff, imag);
-    }
-  } else {
-    barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "-", x);
   }
 }
 
@@ -9599,112 +9686,117 @@ static C_word flo_rat_cmp(C_word flonum, C_word ratnum)
  */
 static C_word basic_cmp(C_word x, C_word y, char *loc, int eqp)
 {
-  if (x & C_FIXNUM_BIT) {
-    if (y & C_FIXNUM_BIT) {
-      return C_fix((x < y) ? -1 : ((x > y) ? 1 : 0));
-    } else if (C_immediatep(y)) {
-      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, y);
-    } else if (C_block_header(y) == C_FLONUM_TAG) {
-      return int_flo_cmp(x, y);
-    } else if (C_truep(C_bignump(y))) {
-      C_word ab[C_SIZEOF_FIX_BIGNUM], *a = ab;
-      return C_i_bignum_cmp(C_a_u_i_fix_to_big(&a, x), y);
-    } else if (C_block_header(y) == C_RATNUM_TAG) {
-      if (eqp) return C_SCHEME_FALSE;
-      else return rat_cmp(x, y);
-    } else if (C_block_header(y) == C_CPLXNUM_TAG) {
-      if (eqp) return C_SCHEME_FALSE;
-      else barf(C_BAD_ARGUMENT_TYPE_COMPLEX_NO_ORDERING_ERROR, loc, y);
-    } else {
-      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, y);
-    }
-  } else if (C_immediatep(x)) {
-    barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, x);
-  } else if (C_block_header(x) == C_FLONUM_TAG) {
-    if (y & C_FIXNUM_BIT) {
-      return flo_int_cmp(x, y);
-    } else if (C_immediatep(y)) {
-      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, y);
-    } else if (C_block_header(y) == C_FLONUM_TAG) {
-      double a = C_flonum_magnitude(x), b = C_flonum_magnitude(y);
-      if (C_isnan(a) || C_isnan(b)) return C_SCHEME_FALSE; /* "mu" */
-      else return C_fix((a < b) ? -1 : ((a > b) ? 1 : 0));
-    } else if (C_truep(C_bignump(y))) {
-      return flo_int_cmp(x, y);
-    } else if (C_block_header(y) == C_RATNUM_TAG) {
-      return flo_rat_cmp(x, y);
-    } else if (C_block_header(y) == C_CPLXNUM_TAG) {
-      if (eqp) return C_SCHEME_FALSE;
-      else barf(C_BAD_ARGUMENT_TYPE_COMPLEX_NO_ORDERING_ERROR, loc, y);
-    } else {
-      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, y);
-    }
-  } else if (C_truep(C_bignump(x))) {
-    if (y & C_FIXNUM_BIT) {
-      C_word ab[C_SIZEOF_FIX_BIGNUM], *a = ab;
-      return C_i_bignum_cmp(x, C_a_u_i_fix_to_big(&a, y));
-    } else if (C_immediatep(y)) {
-      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, y);
-    } else if (C_block_header(y) == C_FLONUM_TAG) {
-      return int_flo_cmp(x, y);
-    } else if (C_truep(C_bignump(y))) {
-      return C_i_bignum_cmp(x, y);
-    } else if (C_block_header(y) == C_RATNUM_TAG) {
-      if (eqp) return C_SCHEME_FALSE;
-      else return rat_cmp(x, y);
-    } else if (C_block_header(y) == C_CPLXNUM_TAG) {
-      if (eqp) return C_SCHEME_FALSE;
-      else barf(C_BAD_ARGUMENT_TYPE_COMPLEX_NO_ORDERING_ERROR, loc, y);
-    } else {
-      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, y);
-    }
-  } else if (C_block_header(x) == C_RATNUM_TAG) {
-    if (y & C_FIXNUM_BIT) {
-      if (eqp) return C_SCHEME_FALSE;
-      else return rat_cmp(x, y);
-    } else if (C_immediatep(y)) {
-      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, y);
-    } else if (C_block_header(y) == C_FLONUM_TAG) {
-      return rat_flo_cmp(x, y);
-    } else if (C_truep(C_bignump(y))) {
-      if (eqp) return C_SCHEME_FALSE;
-      else return rat_cmp(x, y);
-    } else if (C_block_header(y) == C_RATNUM_TAG) {
-      if (eqp) {
-        return C_and(C_and(C_i_integer_equalp(C_u_i_ratnum_num(x),
-                                              C_u_i_ratnum_num(y)),
-                           C_i_integer_equalp(C_u_i_ratnum_denom(x),
-                                              C_u_i_ratnum_denom(y))),
-                     C_fix(0));
-      } else {
-        return rat_cmp(x, y);
-      }
-    } else if (C_block_header(y) == C_CPLXNUM_TAG) {
-      if (eqp) return C_SCHEME_FALSE;
-      else barf(C_BAD_ARGUMENT_TYPE_COMPLEX_NO_ORDERING_ERROR, loc, y);
+  switch(C_dyadic_hash(C_type_hash(x), C_type_hash(y))) {
+  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
+    return C_fix((x < y) ? -1 : ((x > y) ? 1 : 0));
+
+  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
+    return int_flo_cmp(x, y);
+
+  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
+  {
+    C_word ab[C_SIZEOF_FIX_BIGNUM], *a = ab;
+    return C_i_bignum_cmp(C_a_u_i_fix_to_big(&a, x), y);
+  }
+
+  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
+    if (eqp) return C_SCHEME_FALSE;
+    else return rat_cmp(x, y);
+
+  case C_dyadic_hash(C_FIXNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
+    if (eqp) return C_SCHEME_FALSE;
+    else barf(C_BAD_ARGUMENT_TYPE_COMPLEX_NO_ORDERING_ERROR, loc, y);
+
+
+  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
+    return flo_int_cmp(x, y);
+
+  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
+  {
+    double a = C_flonum_magnitude(x), b = C_flonum_magnitude(y);
+    if (C_isnan(a) || C_isnan(b)) return C_SCHEME_FALSE; /* "mu" */
+    else return C_fix((a < b) ? -1 : ((a > b) ? 1 : 0));
+  }
+
+  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
+    return flo_int_cmp(x, y);
+
+  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
+    return flo_rat_cmp(x, y);
+
+  case C_dyadic_hash(C_FLONUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
+    if (eqp) return C_SCHEME_FALSE;
+    else barf(C_BAD_ARGUMENT_TYPE_COMPLEX_NO_ORDERING_ERROR, loc, y);
+
+  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
+  {
+    C_word ab[C_SIZEOF_FIX_BIGNUM], *a = ab;
+    return C_i_bignum_cmp(x, C_a_u_i_fix_to_big(&a, y));
+  }
+
+  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
+    return int_flo_cmp(x, y);
+
+  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
+    return C_i_bignum_cmp(x, y);
+
+  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
+    if (eqp) return C_SCHEME_FALSE;
+    else return rat_cmp(x, y);
+
+  case C_dyadic_hash(C_BIGNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
+    if (eqp) return C_SCHEME_FALSE;
+    else barf(C_BAD_ARGUMENT_TYPE_COMPLEX_NO_ORDERING_ERROR, loc, y);
+
+  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
+    if (eqp) return C_SCHEME_FALSE;
+    else return rat_cmp(x, y);
+
+  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
+    return rat_flo_cmp(x, y);
+
+  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
+    if (eqp) return C_SCHEME_FALSE;
+    else return rat_cmp(x, y);
+
+  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
+    if (eqp) {
+      return C_and(C_and(C_i_integer_equalp(C_u_i_ratnum_num(x),
+                                            C_u_i_ratnum_num(y)),
+                         C_i_integer_equalp(C_u_i_ratnum_denom(x),
+                                            C_u_i_ratnum_denom(y))),
+                   C_fix(0));
     } else {
-      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, y);
+      return rat_cmp(x, y);
     }
-  } else if (C_block_header(x) == C_CPLXNUM_TAG) {
-    if (!eqp) {
+
+  case C_dyadic_hash(C_RATNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
+    if (eqp) return C_SCHEME_FALSE;
+    else barf(C_BAD_ARGUMENT_TYPE_COMPLEX_NO_ORDERING_ERROR, loc, y);
+
+
+  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_FIXNUM_TYPE_HASH):
+  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_FLONUM_TYPE_HASH):
+  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_BIGNUM_TYPE_HASH):
+  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_RATNUM_TYPE_HASH):
+    if (!eqp)
       barf(C_BAD_ARGUMENT_TYPE_COMPLEX_NO_ORDERING_ERROR, loc, x);
-    } else if (y & C_FIXNUM_BIT) {
-      return C_SCHEME_FALSE;
-    } else if (C_immediatep(y)) {
-      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, y);
-    } else if (C_block_header(y) == C_FLONUM_TAG ||
-               C_truep(C_bignump(x)) ||
-               C_block_header(y) == C_RATNUM_TAG) {
+    else
       return C_SCHEME_FALSE;
-    } else if (C_block_header(y) == C_CPLXNUM_TAG) {
+
+  case C_dyadic_hash(C_CPLXNUM_TYPE_HASH, C_CPLXNUM_TYPE_HASH):
+    if (!eqp)
+      barf(C_BAD_ARGUMENT_TYPE_COMPLEX_NO_ORDERING_ERROR, loc, x);
+    else
       return C_and(C_and(C_i_nequalp(C_u_i_cplxnum_real(x), C_u_i_cplxnum_real(y)),
                          C_i_nequalp(C_u_i_cplxnum_imag(x), C_u_i_cplxnum_imag(y))),
                    C_fix(0));
-    } else {
+
+  default:
+    if (!C_truep(C_i_numberp(x)))
+      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, x);
+    else
       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, y);
-    }
-  } else {
-    barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, x);
   }
 }
 
@@ -10582,19 +10674,23 @@ void C_ccall C_string_to_keyword(C_word c, C_word *av)
 C_regparm C_word C_fcall 
 C_a_i_exact_to_inexact(C_word **ptr, int c, C_word n)
 {
-  if (n & C_FIXNUM_BIT) {
+  switch(C_type_hash(n)) {
+  case C_FIXNUM_TYPE_HASH:
     return C_flonum(ptr, (double)C_unfix(n));
-  } else if (C_immediatep(n)) {
-    barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "exact->inexact", n);
-  } else if (C_block_header(n) == C_FLONUM_TAG) {
+
+  case C_FLONUM_TYPE_HASH:
     return n;
-  } else if (C_truep(C_bignump(n))) {
+
+  case C_BIGNUM_TYPE_HASH:
     return C_a_u_i_big_to_flo(ptr, c, n);
-  } else if (C_block_header(n) == C_CPLXNUM_TAG) {
+
+  case C_CPLXNUM_TYPE_HASH:
     return C_cplxnum(ptr, C_a_i_exact_to_inexact(ptr, 1, C_u_i_cplxnum_real(n)),
                      C_a_i_exact_to_inexact(ptr, 1, C_u_i_cplxnum_imag(n)));
+
   /* The horribly painful case: ratnums */
-  } else if (C_block_header(n) == C_RATNUM_TAG) {
+  case C_RATNUM_TYPE_HASH:
+  {
     /* This tries to keep the numbers within representable ranges and
      * tries to drop as few significant digits as possible by bringing
      * the two numbers to within the same powers of two.  See
@@ -10666,7 +10762,9 @@ C_a_i_exact_to_inexact(C_word **ptr, int c, C_word n)
      shift_amount = nmin(DBL_MANT_DIG-1, e - (DBL_MIN_EXP - DBL_MANT_DIG));
      res = ldexp(fraction, e - shift_amount);
      return C_flonum(ptr, C_truep(negp) ? -res : res);
-  } else {
+  }
+
+  default:
     barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "exact->inexact", n);
   }
 }
@@ -11009,6 +11107,7 @@ static char *to_n_nary(C_uword num, C_uword base, int negp, int as_flonum)
 void C_ccall C_number_to_string(C_word c, C_word *av)
 {
   C_word radix, num;
+  C_word k = av[ 1 ];
 
   if(c == 3) {
     radix = C_fix(10);
@@ -11022,17 +11121,22 @@ void C_ccall C_number_to_string(C_word c, C_word *av)
 
   num = av[ 2 ];
 
-  if(num & C_FIXNUM_BIT) {
+  switch(C_type_hash(num)) {
+  case C_FIXNUM_TYPE_HASH:
     C_fixnum_to_string(c, av); /* reuse av */
-  } else if (C_immediatep(num)) {
-    barf(C_BAD_ARGUMENT_TYPE_ERROR, "number->string", num);
-  } else if(C_block_header(num) == C_FLONUM_TAG) {
+
+  case C_FLONUM_TYPE_HASH:
     C_flonum_to_string(c, av); /* reuse av */
-  } else if (C_truep(C_bignump(num))) {
+
+  case C_BIGNUM_TYPE_HASH:
     C_integer_to_string(c, av); /* reuse av */
-  } else {
-    C_word k = av[ 1 ];
+
+  case C_RATNUM_TYPE_HASH:
+  case C_CPLXNUM_TYPE_HASH:
     try_extended_number("##sys#extended-number->string", 3, k, num, radix);
+
+  default:
+    barf(C_BAD_ARGUMENT_TYPE_ERROR, "number->string", num);
   }
 }
 
