diff --git a/runtime.c b/runtime.c
index 93dd9d29..cf7351e7 100644
--- a/runtime.c
+++ b/runtime.c
@@ -269,6 +269,18 @@ static C_TLS int timezone;
 #define C_thread_id(x)   C_block_item((x), 14)
 
 
+/* 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))
+
+/* We only care about numeric type hashes currently */
+#define C_FIXNUM_TYPE_HASH           C_FIXNUM_BIT
+#define C_FLONUM_TYPE_HASH           C_FLONUM_TYPE
+#define C_BIGNUM_TYPE_HASH           C_BIGNUM_TYPE
+#define C_RATNUM_TYPE_HASH           C_RATNUM_TYPE
+#define C_CPLXNUM_TYPE_HASH          C_CPLXNUM_TYPE
+
+
 /* 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 +5299,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 +5379,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 +5399,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 +5428,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 +5457,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 +5488,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 +5519,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 +6432,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 +6463,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 +6493,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,87 +8035,109 @@ 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) {
+  switch(C_type_hash(x)) { /* TODO: Use dyadic_hash? */
+  case C_FIXNUM_TYPE_HASH:
+    switch(C_type_hash(y)) {
+    case C_FIXNUM_TYPE_HASH:
       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) {
+
+    case C_FLONUM_TYPE_HASH:
       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)) {
-      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))) {
+
+    case C_BIGNUM_TYPE_HASH:
       return C_s_a_u_i_integer_times(ptr, 2, x, y);
-    } else if (C_block_header(y) == C_RATNUM_TAG) {
+
+    case C_RATNUM_TYPE_HASH:
       return rat_times_integer(ptr, y, x);
-    } else if (C_block_header(y) == C_CPLXNUM_TAG) {
+
+    case C_CPLXNUM_TYPE_HASH:
       return cplx_times(ptr, x, C_fix(0),
                         C_u_i_cplxnum_real(y), C_u_i_cplxnum_imag(y));
-    } else {
+
+    default:
       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) {
+
+    case C_FLONUM_TYPE_HASH:
+      switch(C_type_hash(y)) {
+      case C_FIXNUM_TYPE_HASH:
+        return C_flonum(ptr, C_flonum_magnitude(x) * (double)C_unfix(y));
+
+      case C_FLONUM_TYPE_HASH:
+        return C_a_i_flonum_times(ptr, 2, x, y);
+
+      case C_BIGNUM_TYPE_HASH:
+        return C_flonum(ptr, C_flonum_magnitude(x) * C_bignum_to_double(y));
+
+      case C_RATNUM_TYPE_HASH:
+        return C_s_a_i_times(ptr, 2, x, C_a_i_exact_to_inexact(ptr, 1, y));
+
+      case 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));
+      }
+
+      default:
+        barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "*", y);
+      }
+
+    case C_BIGNUM_TYPE_HASH:
+      switch(C_type_hash(y)) {
+      case C_FIXNUM_TYPE_HASH:
+        return C_s_a_u_i_integer_times(ptr, 2, x, y);
+
+      case C_FLONUM_TYPE_HASH:
+        return C_flonum(ptr, C_bignum_to_double(x) * C_flonum_magnitude(y));
+
+      case C_BIGNUM_TYPE_HASH:
+        return C_s_a_u_i_integer_times(ptr, 2, x, y);
+
+      case C_RATNUM_TYPE_HASH:
+        return rat_times_integer(ptr, y, x);
+
+      case C_CPLXNUM_TYPE_HASH:
+        return cplx_times(ptr, x, C_fix(0),
+                          C_u_i_cplxnum_real(y), C_u_i_cplxnum_imag(y));
+
+      default:
+        barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "*", y);
+      }
+
+    case C_RATNUM_TYPE_HASH:
+      switch(C_type_hash(y)) {
+      case C_FIXNUM_TYPE_HASH:
+        return rat_times_integer(ptr, x, y);
+
+      case C_FLONUM_TYPE_HASH:
+        return C_s_a_i_times(ptr, 2, C_a_i_exact_to_inexact(ptr, 1, x), y);
+
+      case C_BIGNUM_TYPE_HASH:
+        return rat_times_integer(ptr, x, y);
+
+      case C_RATNUM_TYPE_HASH:
         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 {
-      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 {
+
+      case C_CPLXNUM_TYPE_HASH:
+        return cplx_times(ptr, x, C_fix(0),
+                          C_u_i_cplxnum_real(y), C_u_i_cplxnum_imag(y));
+
+      default:
+        barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "*", y);
+      }
+
+    case C_CPLXNUM_TYPE_HASH:
+      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);
+      }
+
+  default:
     barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "*", x);
   }
 }
@@ -8382,89 +8452,113 @@ 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) {
+  switch(C_type_hash(x)) { /* TODO: Use dyadic_hash? */
+  case C_FIXNUM_TYPE_HASH:
+    switch(C_type_hash(y)) {
+    case C_FIXNUM_TYPE_HASH:
       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) {
+
+    case C_FLONUM_TYPE_HASH:
       return C_flonum(ptr, (double)C_unfix(x) + C_flonum_magnitude(y));
-    } else if (C_truep(C_bignump(y))) {
+
+    case C_BIGNUM_TYPE_HASH:
       return C_s_a_u_i_integer_plus(ptr, 2, x, y);
-    } else if (C_block_header(y) == C_RATNUM_TAG) {
+
+    case C_RATNUM_TYPE_HASH:
       return rat_plusmin_integer(ptr, y, x, C_s_a_u_i_integer_plus);
-    } else if (C_block_header(y) == C_CPLXNUM_TAG) {
+
+    case 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);
-    } 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 {
+
+    default:
       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "+", y);
     }
-  } else if (C_truep(C_bignump(x))) {
-    if (y & C_FIXNUM_BIT) {
+
+    case C_FLONUM_TYPE_HASH:
+      switch(C_type_hash(y)) {
+      case C_FIXNUM_TYPE_HASH:
+        return C_flonum(ptr, C_flonum_magnitude(x) + (double)C_unfix(y));
+
+      case C_FLONUM_TYPE_HASH:
+        return C_a_i_flonum_plus(ptr, 2, x, y);
+
+      case C_BIGNUM_TYPE_HASH:
+        return C_flonum(ptr, C_flonum_magnitude(x)+C_bignum_to_double(y));
+
+      case C_RATNUM_TYPE_HASH:
+        return C_s_a_i_plus(ptr, 2, x, C_a_i_exact_to_inexact(ptr, 1, y));
+
+      case 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);
+      }
+
+      default:
+        barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "+", y);
+    }
+
+  case C_BIGNUM_TYPE_HASH:
+    switch(C_type_hash(y)) {
+    case C_FIXNUM_TYPE_HASH:
       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) {
+    case C_FLONUM_TYPE_HASH:
       return C_flonum(ptr, C_bignum_to_double(x)+C_flonum_magnitude(y));
-    } else if (C_truep(C_bignump(y))) {
+
+    case C_BIGNUM_TYPE_HASH:
       return C_s_a_u_i_integer_plus(ptr, 2, x, y);
-    } else if (C_block_header(y) == C_RATNUM_TAG) {
+
+    case C_RATNUM_TYPE_HASH:
       return rat_plusmin_integer(ptr, y, x, C_s_a_u_i_integer_plus);
-    } else if (C_block_header(y) == C_CPLXNUM_TAG) {
+
+    case 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);
+        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 {
+    }
+      
+    default:
       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "+", y);
     }
-  } else if (C_block_header(x) == C_RATNUM_TAG) {
-    if (y & C_FIXNUM_BIT) {
+
+  case C_RATNUM_TYPE_HASH:
+    switch(C_type_hash(y)) {
+    case C_FIXNUM_TYPE_HASH:
+    case C_BIGNUM_TYPE_HASH:
       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) {
+
+    case C_FLONUM_TYPE_HASH:
       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) {
+
+    case C_RATNUM_TYPE_HASH:
       return rat_plusmin_rat(ptr, x, y, C_s_a_u_i_integer_plus);
-    } else if (C_block_header(y) == C_CPLXNUM_TAG) {
+
+    case 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);
+        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 {
+    }
+
+    default:
       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "+", y);
     }
-  } else if (C_block_header(x) == C_CPLXNUM_TAG) {
+
+  case C_CPLXNUM_TYPE_HASH:
     if (!C_immediatep(y) && C_block_header(y) == C_CPLXNUM_TAG) {
       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));
@@ -8473,12 +8567,13 @@ C_s_a_i_plus(C_word **ptr, C_word n, C_word x, C_word y)
       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);
+        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 {
+
+  default:
     barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "+", x);
   }
 }
@@ -8593,89 +8688,116 @@ 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) {
+  switch(C_type_hash(x)) { /* TODO: Use dyadic_hash? */
+  case C_FIXNUM_TYPE_HASH:
+    switch(C_type_hash(y)) {
+    case C_FIXNUM_TYPE_HASH:
       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) {
+
+    case C_FLONUM_TYPE_HASH:
       return C_flonum(ptr, (double)C_unfix(x) - C_flonum_magnitude(y));
-    } else if (C_truep(C_bignump(y))) {
+
+    case C_BIGNUM_TYPE_HASH:
       return C_s_a_u_i_integer_minus(ptr, 2, x, y);
-    } else if (C_block_header(y) == C_RATNUM_TAG) {
+
+    case C_RATNUM_TYPE_HASH:
       return integer_minus_rat(ptr, x, y);
-    } else if (C_block_header(y) == C_CPLXNUM_TAG) {
+
+    case 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);
-    } else {
+    }
+
+    default:
       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) {
+
+  case C_FLONUM_TYPE_HASH:
+    switch(C_type_hash(y)) {
+    case C_FIXNUM_TYPE_HASH:
       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) {
+
+    case C_FLONUM_TYPE_HASH:
       return C_a_i_flonum_difference(ptr, 2, x, y);
-    } else if (C_truep(C_bignump(y))) {
+
+    case C_BIGNUM_TYPE_HASH:
       return C_flonum(ptr, C_flonum_magnitude(x)-C_bignum_to_double(y));
-    } else if (C_block_header(y) == C_RATNUM_TAG) {
+
+    case C_RATNUM_TYPE_HASH:
       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) {
+
+    case 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);
-    } else {
+    }
+
+    default:
       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "-", y);
     }
-  } else if (C_truep(C_bignump(x))) {
-    if (y & C_FIXNUM_BIT) {
+
+  case C_BIGNUM_TYPE_HASH:
+    switch(C_type_hash(y)) {
+    case C_FIXNUM_TYPE_HASH:
       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) {
+
+    case C_FLONUM_TYPE_HASH:
       return C_flonum(ptr, C_bignum_to_double(x)-C_flonum_magnitude(y));
-    } else if (C_truep(C_bignump(y))) {
+
+    case C_BIGNUM_TYPE_HASH:
       return C_s_a_u_i_integer_minus(ptr, 2, x, y);
-    } else if (C_block_header(y) == C_RATNUM_TAG) {
+
+    case C_RATNUM_TYPE_HASH:
       return integer_minus_rat(ptr, x, y);
-    } else if (C_block_header(y) == C_CPLXNUM_TAG) {
+
+    case 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);
-    } else {
+    }
+
+    default:
       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "-", y);
     }
-  } else if (C_block_header(x) == C_RATNUM_TAG) {
-    if (y & C_FIXNUM_BIT) {
+
+  case C_RATNUM_TYPE_HASH:
+    switch(C_type_hash(y)) {
+    case C_FIXNUM_TYPE_HASH:
       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) {
+
+    case C_FLONUM_TYPE_HASH:
       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))) {
+
+    case C_BIGNUM_TYPE_HASH:
       return rat_plusmin_integer(ptr, x, y, C_s_a_u_i_integer_minus);
-    } else if (C_block_header(y) == C_RATNUM_TAG) {
+
+    case C_RATNUM_TYPE_HASH:
       return rat_plusmin_rat(ptr, x, y, C_s_a_u_i_integer_minus);
-    } else if (C_block_header(y) == C_CPLXNUM_TAG) {
+
+    case 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);
-    } else {
+    }
+
+    default:
       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "-", y);
     }
-  } else if (C_block_header(x) == C_CPLXNUM_TAG) {
+
+  case C_CPLXNUM_TYPE_HASH:
     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));
@@ -8689,7 +8811,8 @@ C_s_a_i_minus(C_word **ptr, C_word n, C_word x, C_word y)
         imag = C_a_i_exact_to_inexact(ptr, 1, imag);
       return C_cplxnum(ptr, real_diff, imag);
     }
-  } else {
+
+  default:
     barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "-", x);
   }
 }
@@ -9599,77 +9722,99 @@ 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) {
+  switch(C_type_hash(x)) { /* TODO: Use dyadic_hash? */
+  case C_FIXNUM_TYPE_HASH:
+    switch(C_type_hash(y)) {
+    case C_FIXNUM_TYPE_HASH:
       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) {
+
+    case C_FLONUM_TYPE_HASH:
       return int_flo_cmp(x, y);
-    } else if (C_truep(C_bignump(y))) {
+
+    case 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);
-    } else if (C_block_header(y) == C_RATNUM_TAG) {
+    }
+
+    case C_RATNUM_TYPE_HASH:
       if (eqp) return C_SCHEME_FALSE;
       else return rat_cmp(x, y);
-    } else if (C_block_header(y) == C_CPLXNUM_TAG) {
+
+    case C_CPLXNUM_TYPE_HASH:
       if (eqp) return C_SCHEME_FALSE;
       else barf(C_BAD_ARGUMENT_TYPE_COMPLEX_NO_ORDERING_ERROR, loc, y);
-    } else {
+
+    default:
       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) {
+
+  case C_FLONUM_TYPE_HASH:
+    switch(C_type_hash(y)) {
+    case C_FIXNUM_TYPE_HASH:
       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) {
+
+    case 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));
-    } else if (C_truep(C_bignump(y))) {
+    }
+
+    case C_BIGNUM_TYPE_HASH:
       return flo_int_cmp(x, y);
-    } else if (C_block_header(y) == C_RATNUM_TAG) {
+
+    case C_RATNUM_TYPE_HASH:
       return flo_rat_cmp(x, y);
-    } else if (C_block_header(y) == C_CPLXNUM_TAG) {
+
+    case C_CPLXNUM_TYPE_HASH:
       if (eqp) return C_SCHEME_FALSE;
       else barf(C_BAD_ARGUMENT_TYPE_COMPLEX_NO_ORDERING_ERROR, loc, y);
-    } else {
+
+    default:
       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, y);
     }
-  } else if (C_truep(C_bignump(x))) {
-    if (y & C_FIXNUM_BIT) {
+
+  case C_BIGNUM_TYPE_HASH:
+    switch(C_type_hash(y)) {
+    case 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));
-    } else if (C_immediatep(y)) {
-      barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, y);
-    } else if (C_block_header(y) == C_FLONUM_TAG) {
+    }
+
+    case C_FLONUM_TYPE_HASH:
       return int_flo_cmp(x, y);
-    } else if (C_truep(C_bignump(y))) {
+
+    case C_BIGNUM_TYPE_HASH:
       return C_i_bignum_cmp(x, y);
-    } else if (C_block_header(y) == C_RATNUM_TAG) {
+
+    case C_RATNUM_TYPE_HASH:
       if (eqp) return C_SCHEME_FALSE;
       else return rat_cmp(x, y);
-    } else if (C_block_header(y) == C_CPLXNUM_TAG) {
+
+    case C_CPLXNUM_TYPE_HASH:
       if (eqp) return C_SCHEME_FALSE;
       else barf(C_BAD_ARGUMENT_TYPE_COMPLEX_NO_ORDERING_ERROR, loc, y);
-    } else {
+
+    default:
       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, y);
     }
-  } else if (C_block_header(x) == C_RATNUM_TAG) {
-    if (y & C_FIXNUM_BIT) {
+
+  case C_RATNUM_TYPE_HASH:
+    switch(C_type_hash(y)) {
+    case C_FIXNUM_TYPE_HASH:
       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) {
+
+    case C_FLONUM_TYPE_HASH:
       return rat_flo_cmp(x, y);
-    } else if (C_truep(C_bignump(y))) {
+
+    case C_BIGNUM_TYPE_HASH:
       if (eqp) return C_SCHEME_FALSE;
       else return rat_cmp(x, y);
-    } else if (C_block_header(y) == C_RATNUM_TAG) {
+
+    case 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)),
@@ -9679,31 +9824,36 @@ static C_word basic_cmp(C_word x, C_word y, char *loc, int eqp)
       } else {
         return rat_cmp(x, y);
       }
-    } else if (C_block_header(y) == C_CPLXNUM_TAG) {
+
+    case C_CPLXNUM_TYPE_HASH:
       if (eqp) return C_SCHEME_FALSE;
       else barf(C_BAD_ARGUMENT_TYPE_COMPLEX_NO_ORDERING_ERROR, loc, y);
-    } else {
+
+    default:
       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, y);
     }
-  } else if (C_block_header(x) == C_CPLXNUM_TAG) {
-    if (!eqp) {
+
+  case C_CPLXNUM_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) {
+
+    switch(C_type_hash(y)) {
+    case C_FIXNUM_TYPE_HASH:
+    case C_FLONUM_TYPE_HASH:
+    case C_BIGNUM_TYPE_HASH:
+    case C_RATNUM_TYPE_HASH:
       return C_SCHEME_FALSE;
-    } else if (C_block_header(y) == C_CPLXNUM_TAG) {
+
+    case C_CPLXNUM_TYPE_HASH:
       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:
       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, y);
     }
-  } else {
+
+  default:
     barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, x);
   }
 }
@@ -10582,19 +10732,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 +10820,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 +11165,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 +11179,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);
   }
 }
 
