* numbers.c (scm_string_to_number): Signal an error if radix is
[bpt/guile.git] / libguile / numbers.c
index a3fd4cc..7695628 100644 (file)
@@ -1,4 +1,4 @@
-/*      Copyright (C) 1995,1996,1997,1998 Free Software Foundation, Inc.
+/*      Copyright (C) 1995,1996,1997,1998, 1999 Free Software Foundation, Inc.
 
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -45,6 +45,8 @@
 #include "_scm.h"
 #include "genio.h"
 #include "unif.h"
+#include "feature.h"
+#include "smob.h"
 
 #include "numbers.h"
 \f
 #define IS_INF(x) ((x) == (x) / 2)
 #endif
 
+/* Return true if X is not infinite and is not a NaN
+ */
+#ifndef isfinite
+#define isfinite(x) (!IS_INF (x) && (x) == (x))
+#endif
+
 /* MAXEXP is the maximum double precision expontent
  * FLTMAX is less than or scm_equal the largest single precision float
  */
@@ -133,7 +141,7 @@ scm_even_p (n)
   return (4 & (int) n) ? SCM_BOOL_F : SCM_BOOL_T;
 }
 
-SCM_PROC (s_abs, "abs", 1, 0, 0, scm_abs);
+SCM_GPROC (s_abs, "abs", 1, 0, 0, scm_abs, g_abs);
 
 SCM
 scm_abs (x)
@@ -142,13 +150,13 @@ scm_abs (x)
 #ifdef SCM_BIGDIG
   if (SCM_NINUMP (x))
     {
-      SCM_ASSERT (SCM_NIMP (x) && SCM_BIGP (x), x, SCM_ARG1, s_abs);
+      SCM_GASSERT1 (SCM_NIMP (x) && SCM_BIGP (x), g_abs, x, SCM_ARG1, s_abs);
       if (SCM_TYP16 (x) == scm_tc16_bigpos)
        return x;
       return scm_copybig (x, 0);
     }
 #else
-  SCM_ASSERT (SCM_INUMP (x), x, SCM_ARG1, s_abs);
+  SCM_GASSERT1 (SCM_INUMP (x), g_abs, x, SCM_ARG1, s_abs);
 #endif
   if (SCM_INUM (x) >= 0)
     return x;
@@ -162,7 +170,7 @@ scm_abs (x)
   return SCM_MAKINUM (x);
 }
 
-SCM_PROC (s_quotient, "quotient", 2, 0, 0, scm_quotient);
+SCM_GPROC (s_quotient, "quotient", 2, 0, 0, scm_quotient, g_quotient);
 
 SCM
 scm_quotient (x, y)
@@ -174,7 +182,8 @@ scm_quotient (x, y)
   if (SCM_NINUMP (x))
     {
       long w;
-      SCM_ASSERT (SCM_NIMP (x) && SCM_BIGP (x), x, SCM_ARG1, s_quotient);
+      SCM_GASSERT2 (SCM_NIMP (x) && SCM_BIGP (x),
+                   g_quotient, x, y, SCM_ARG1, s_quotient);
       if (SCM_NINUMP (y))
        {
          SCM_ASRTGO (SCM_NIMP (y) && SCM_BIGP (y), bady);
@@ -211,18 +220,16 @@ scm_quotient (x, y)
     }
   if (SCM_NINUMP (y))
     {
-#ifndef SCM_RECKLESS
       if (!(SCM_NIMP (y) && SCM_BIGP (y)))
        {
        bady:
-         scm_wta (y, (char *) SCM_ARG2, s_quotient);
+         SCM_WTA_DISPATCH_2 (g_quotient, x, y, SCM_ARG2, s_quotient);
        }
-#endif
       return SCM_INUM0;
     }
 #else
-  SCM_ASSERT (SCM_INUMP (x), x, SCM_ARG1, s_quotient);
-  SCM_ASSERT (SCM_INUMP (y), y, SCM_ARG2, s_quotient);
+  SCM_GASSERT2 (SCM_INUMP (x), g_quotient, x, y, SCM_ARG1, s_quotient);
+  SCM_GASSERT2 (SCM_INUMP (y), g_quotient, x, y, SCM_ARG2, s_quotient);
 #endif
   if ((z = SCM_INUM (y)) == 0)
     {
@@ -255,7 +262,7 @@ scm_quotient (x, y)
   return SCM_MAKINUM (z);
 }
 
-SCM_PROC (s_remainder, "remainder", 2, 0, 0, scm_remainder);
+SCM_GPROC (s_remainder, "remainder", 2, 0, 0, scm_remainder, g_remainder);
 
 SCM
 scm_remainder (x, y)
@@ -266,7 +273,8 @@ scm_remainder (x, y)
 #ifdef SCM_BIGDIG
   if (SCM_NINUMP (x))
     {
-      SCM_ASSERT (SCM_NIMP (x) && SCM_BIGP (x), x, SCM_ARG1, s_remainder);
+      SCM_GASSERT2 (SCM_NIMP (x) && SCM_BIGP (x),
+                   g_remainder, x, y, SCM_ARG1, s_remainder);
       if (SCM_NINUMP (y))
        {
          SCM_ASRTGO (SCM_NIMP (y) && SCM_BIGP (y), bady);
@@ -280,18 +288,16 @@ scm_remainder (x, y)
     }
   if (SCM_NINUMP (y))
     {
-#ifndef SCM_RECKLESS
       if (!(SCM_NIMP (y) && SCM_BIGP (y)))
        {
        bady:
-         scm_wta (y, (char *) SCM_ARG2, s_remainder);
+         SCM_WTA_DISPATCH_2 (g_remainder, x, y, SCM_ARG2, s_remainder);
        }
-#endif
       return x;
     }
 #else
-  SCM_ASSERT (SCM_INUMP (x), x, SCM_ARG1, s_remainder);
-  SCM_ASSERT (SCM_INUMP (y), y, SCM_ARG2, s_remainder);
+  SCM_GASSERT2 (SCM_INUMP (x), g_remainder, x, y, SCM_ARG1, s_remainder);
+  SCM_GASSERT2 (SCM_INUMP (y), g_remainder, x, y, SCM_ARG2, s_remainder);
 #endif
   if (!(z = SCM_INUM (y)))
     {
@@ -315,7 +321,7 @@ scm_remainder (x, y)
   return SCM_MAKINUM (z);
 }
 
-SCM_PROC (s_modulo, "modulo", 2, 0, 0, scm_modulo);
+SCM_GPROC (s_modulo, "modulo", 2, 0, 0, scm_modulo, g_modulo);
 
 SCM
 scm_modulo (x, y)
@@ -326,7 +332,8 @@ scm_modulo (x, y)
 #ifdef SCM_BIGDIG
   if (SCM_NINUMP (x))
     {
-      SCM_ASSERT (SCM_NIMP (x) && SCM_BIGP (x), x, SCM_ARG1, s_modulo);
+      SCM_GASSERT2 (SCM_NIMP (x) && SCM_BIGP (x),
+                   g_modulo, x, y, SCM_ARG1, s_modulo);
       if (SCM_NINUMP (y))
        {
          SCM_ASRTGO (SCM_NIMP (y) && SCM_BIGP (y), bady);
@@ -342,18 +349,16 @@ scm_modulo (x, y)
     }
   if (SCM_NINUMP (y))
     {
-#ifndef SCM_RECKLESS
       if (!(SCM_NIMP (y) && SCM_BIGP (y)))
        {
        bady:
-         scm_wta (y, (char *) SCM_ARG2, s_modulo);
+         SCM_WTA_DISPATCH_2 (g_modulo, x, y, SCM_ARG2, s_modulo);
        }
-#endif
       return (SCM_BIGSIGN (y) ? (x > 0) : (x < 0)) ? scm_sum (x, y) : x;
     }
 #else
-  SCM_ASSERT (SCM_INUMP (x), x, SCM_ARG1, s_modulo);
-  SCM_ASSERT (SCM_INUMP (y), y, SCM_ARG2, s_modulo);
+  SCM_GASSERT1 (SCM_INUMP (x), g_modulo, x, y, SCM_ARG1, s_modulo);
+  SCM_GASSERT2 (SCM_INUMP (y), g_modulo, x, y, SCM_ARG2, s_modulo);
 #endif
   if (!(yy = SCM_INUM (y)))
     {
@@ -369,7 +374,7 @@ scm_modulo (x, y)
   return SCM_MAKINUM (((yy < 0) ? (z > 0) : (z < 0)) ? z + yy : z);
 }
 
-SCM_PROC1 (s_gcd, "gcd", scm_tc7_asubr, scm_gcd);
+SCM_GPROC1 (s_gcd, "gcd", scm_tc7_asubr, scm_gcd, g_gcd);
 
 SCM
 scm_gcd (x, y)
@@ -384,13 +389,15 @@ scm_gcd (x, y)
   if (SCM_NINUMP (x))
     {
     big_gcd:
-      SCM_ASSERT (SCM_NIMP (x) && SCM_BIGP (x), x, SCM_ARG1, s_gcd);
+      SCM_GASSERT2 (SCM_NIMP (x) && SCM_BIGP (x),
+                   g_gcd, x, y, SCM_ARG1, s_gcd);
       if (SCM_BIGSIGN (x))
        x = scm_copybig (x, 0);
     newy:
       if (SCM_NINUMP (y))
        {
-         SCM_ASSERT (SCM_NIMP (y) && SCM_BIGP (y), y, SCM_ARG2, s_gcd);
+         SCM_GASSERT2 (SCM_NIMP (y) && SCM_BIGP (y),
+                       g_gcd, x, y, SCM_ARGn, s_gcd);
          if (SCM_BIGSIGN (y))
            y = scm_copybig (y, 0);
          switch (scm_bigcomp (x, y))
@@ -422,8 +429,8 @@ scm_gcd (x, y)
       goto big_gcd;
     }
 #else
-  SCM_ASSERT (SCM_INUMP (x), x, SCM_ARG1, s_gcd);
-  SCM_ASSERT (SCM_INUMP (y), y, SCM_ARG2, s_gcd);
+  SCM_GASSERT2 (SCM_INUMP (x), g_gcd, x, y, SCM_ARG1, s_gcd);
+  SCM_GASSERT2 (SCM_INUMP (y), g_gcd, x, y, SCM_ARGn, s_gcd);
 #endif
   u = SCM_INUM (x);
   if (u < 0)
@@ -466,7 +473,7 @@ scm_gcd (x, y)
   return SCM_MAKINUM (u);
 }
 
-SCM_PROC1 (s_lcm, "lcm", scm_tc7_asubr, scm_lcm);
+SCM_GPROC1 (s_lcm, "lcm", scm_tc7_asubr, scm_lcm, g_lcm);
 
 SCM
 scm_lcm (n1, n2)
@@ -474,12 +481,28 @@ scm_lcm (n1, n2)
      SCM n2;
 {
   SCM d;
+#ifndef SCM_BIGDIG
+  SCM_GASSERT2 (SCM_INUMP (n1) || SCM_UNBNDP (n1),
+               g_lcm, n1, n2, SCM_ARG1, s_lcm);
+  SCM_GASSERT2 (SCM_INUMP (n2) || SCM_UNBNDP (n2),
+               g_lcm, n1, n2, SCM_ARGn, s_lcm);
+#else
+  SCM_GASSERT2 (SCM_INUMP (n1)
+               || SCM_UNBNDP (n1)
+               || (SCM_NIMP (n1) && SCM_BIGP (n1)),
+               g_lcm, n1, n2, SCM_ARG1, s_lcm);
+  SCM_GASSERT2 (SCM_INUMP (n2)
+               || SCM_UNBNDP (n2)
+               || (SCM_NIMP (n2) && SCM_BIGP (n2)),
+               g_lcm, n1, n2, SCM_ARGn, s_lcm);
+#endif
   if (SCM_UNBNDP (n2))
     {
       n2 = SCM_MAKINUM (1L);
       if (SCM_UNBNDP (n1))
        return n2;
     }
+  
   d = scm_gcd (n1, n2);
   if (SCM_INUM0 == d)
     return d;
@@ -747,7 +770,9 @@ scm_bit_extract (n, start, end)
   return SCM_MAKINUM ((SCM_INUM (n) >> start) & ((1L << (end - start)) - 1));
 }
 
-char scm_logtab[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
+static const char scm_logtab[] = {
+  0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
+};
 SCM_PROC (s_logcount, "logcount", 1, 0, 0, scm_logcount);
 
 SCM
@@ -780,7 +805,9 @@ scm_logcount (n)
   return SCM_MAKINUM (c);
 }
 
-char scm_ilentab[] = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4 };
+static const char scm_ilentab[] = {
+  0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4
+};
 SCM_PROC (s_integer_length, "integer-length", 1, 0, 0, scm_integer_length);
 
 SCM
@@ -821,7 +848,7 @@ scm_integer_length (n)
 
 
 #ifdef SCM_BIGDIG
-char scm_s_bignum[] = "bignum";
+static const char s_bignum[] = "bignum";
 
 SCM
 scm_mkbig (nlen, sign)
@@ -831,11 +858,11 @@ scm_mkbig (nlen, sign)
   SCM v = nlen;
   /* Cast to SCM to avoid signed/unsigned comparison warnings.  */
   if (((v << 16) >> 16) != (SCM) nlen)
-    scm_wta (SCM_MAKINUM (nlen), (char *) SCM_NALLOC, scm_s_bignum);
+    scm_wta (SCM_MAKINUM (nlen), (char *) SCM_NALLOC, s_bignum);
   SCM_NEWCELL (v);
   SCM_DEFER_INTS;
   SCM_SETCHARS (v, scm_must_malloc ((long) (nlen * sizeof (SCM_BIGDIG)),
-                                   scm_s_bignum));
+                                   s_bignum));
   SCM_SETNUMDIGS (v, nlen, sign ? scm_tc16_bigneg : scm_tc16_bigpos);
   SCM_ALLOW_INTS;
   return v;
@@ -862,7 +889,7 @@ scm_big2inum (b, l)
 }
 
 
-char s_adjbig[] = "scm_adjbig";
+static const char s_adjbig[] = "scm_adjbig";
 
 SCM
 scm_adjbig (b, nlen)
@@ -1515,7 +1542,7 @@ scm_divbigbig (x, nx, y, ny, sgn, modes)
 /*** NUMBERS -> STRINGS ***/
 #ifdef SCM_FLOATS
 int scm_dblprec;
-static double fx[] =
+static const double fx[] =
 {  0.0,  5e-1,  5e-2,  5e-3,   5e-4, 5e-5,
   5e-6,  5e-7,  5e-8,  5e-9,  5e-10,
  5e-11, 5e-12, 5e-13, 5e-14,  5e-15,
@@ -1793,7 +1820,11 @@ scm_number_to_string (x, radix)
   if (SCM_UNBNDP (radix))
     radix = SCM_MAKINUM (10L);
   else
-    SCM_ASSERT (SCM_INUMP (radix), radix, SCM_ARG2, s_number_to_string);
+    {
+      SCM_ASSERT (SCM_INUMP (radix), radix, SCM_ARG2, s_number_to_string);
+      SCM_ASSERT (SCM_INUM (radix) >= 2, radix, SCM_OUTOFRANGE,
+                 s_number_to_string);
+    }
 #ifdef SCM_FLOATS
   if (SCM_NINUMP (x))
     {
@@ -2302,7 +2333,7 @@ scm_istr2flo (str, len, radix)
       {                                /* polar input for complex number */
        /* get a `real' for scm_angle */
        second = scm_istr2flo (&str[i], (long) (len - i), radix);
-       if (!(SCM_INEXP (second)))
+       if (!(SCM_NIMP (second) && SCM_INEXP (second)))
          return SCM_BOOL_F;    /* not `real' */
        if (SCM_CPLXP (second))
          return SCM_BOOL_F;    /* not `real' */
@@ -2321,7 +2352,7 @@ scm_istr2flo (str, len, radix)
     return scm_makdbl (res, lead_sgn);
   /* get a `ureal' for complex part */
   second = scm_istr2flo (&str[i], (long) ((len - i) - 1), radix);
-  if (!(SCM_INEXP (second)))
+  if (! (SCM_NIMP (second) && SCM_INEXP (second)))
     return SCM_BOOL_F;         /* not `ureal' */
   if (SCM_CPLXP (second))
     return SCM_BOOL_F;         /* not `ureal' */
@@ -2419,7 +2450,11 @@ scm_string_to_number (str, radix)
   if (SCM_UNBNDP (radix))
     radix = SCM_MAKINUM (10L);
   else
-    SCM_ASSERT (SCM_INUMP (radix), radix, SCM_ARG2, s_string_to_number);
+    {
+      SCM_ASSERT (SCM_INUMP (radix), radix, SCM_ARG2, s_string_to_number);
+      SCM_ASSERT (SCM_INUM (radix) >= 2, radix, SCM_OUTOFRANGE,
+                 s_number_to_string);
+    }
   SCM_ASSERT (SCM_NIMP (str) && SCM_ROSTRINGP (str),
              str, SCM_ARG1, s_string_to_number);
   answer = scm_istring2number (SCM_ROCHARS (str),
@@ -2439,7 +2474,6 @@ scm_makdbl (x, y)
   SCM z;
   if ((y == 0.0) && (x == 0.0))
     return scm_flo0;
-  SCM_NEWCELL (z);
   SCM_DEFER_INTS;
   if (y == 0.0)
     {
@@ -2449,19 +2483,17 @@ scm_makdbl (x, y)
       if ((-FLTMAX < x) && (x < FLTMAX) && (fx == x))
 #endif
        {
-         SCM_SETCAR (z, scm_tc_flo);
+          SCM_NEWSMOB(z,scm_tc_flo,NULL);
          SCM_FLO (z) = x;
          SCM_ALLOW_INTS;
          return z;
        }
 #endif /* def SCM_SINGLES */
-      SCM_SETCDR (z, (SCM) scm_must_malloc (1L * sizeof (double), "real"));
-      SCM_SETCAR (z, scm_tc_dblr);
+      SCM_NEWSMOB(z,scm_tc_dblr,scm_must_malloc (1L * sizeof (double), "real"));
     }
   else
     {
-      SCM_SETCDR (z, (SCM) scm_must_malloc (2L * sizeof (double), "complex"));
-      SCM_SETCAR (z, scm_tc_dblc);
+      SCM_NEWSMOB(z,scm_tc_dblc,scm_must_malloc (2L * sizeof (double), "comkplex"));
       SCM_IMAG (z) = y;
     }
   SCM_REAL (z) = x;
@@ -2594,7 +2626,7 @@ scm_inexact_p (x)
 
 
 
-SCM_PROC1 (s_eq_p, "=", scm_tc7_rpsubr, scm_num_eq_p);
+SCM_GPROC1 (s_eq_p, "=", scm_tc7_rpsubr, scm_num_eq_p, g_eq_p);
 
 SCM
 scm_num_eq_p (x, y)
@@ -2606,13 +2638,11 @@ scm_num_eq_p (x, y)
   if (SCM_NINUMP (x))
     {
 #ifdef SCM_BIGDIG
-#ifndef SCM_RECKLESS
       if (!(SCM_NIMP (x)))
        {
        badx:
-         scm_wta (x, (char *) SCM_ARG1, s_eq_p);
+         SCM_WTA_DISPATCH_2 (g_eq_p, x, y, SCM_ARG1, s_eq_p);
        }
-#endif
       if (SCM_BIGP (x))
        {
          if (SCM_INUMP (y))
@@ -2628,7 +2658,8 @@ scm_num_eq_p (x, y)
        }
       SCM_ASRTGO (SCM_INEXP (x), badx);
 #else
-      SCM_ASSERT (SCM_NIMP (x) && SCM_INEXP (x), x, SCM_ARG1, s_eq_p);
+      SCM_GASSERT2 (SCM_NIMP (x) && SCM_INEXP (x),
+                   g_eq_p, x, y, SCM_ARG1, s_eq_p);
 #endif
       if (SCM_INUMP (y))
        {
@@ -2664,21 +2695,17 @@ scm_num_eq_p (x, y)
       SCM_ASRTGO (SCM_NIMP (y), bady);
       if (SCM_BIGP (y))
        return SCM_BOOL_F;
-#ifndef SCM_RECKLESS
       if (!(SCM_INEXP (y)))
        {
        bady:
-         scm_wta (y, (char *) SCM_ARG2, s_eq_p);
+         SCM_WTA_DISPATCH_2 (g_eq_p, x, y, SCM_ARGn, s_eq_p);
        }
-#endif
 #else
-#ifndef SCM_RECKLESS
       if (!(SCM_NIMP (y) && SCM_INEXP (y)))
        {
        bady:
-         scm_wta (y, (char *) SCM_ARG2, s_eq_p);
+         SCM_WTA_DISPATCH_2 (g_eq_p, x, y, SCM_ARGn, s_eq_p);
        }
-#endif
 #endif
     realint:
       return ((SCM_REALP (y) && (((double) SCM_INUM (x)) == SCM_REALPART (y)))
@@ -2689,7 +2716,8 @@ scm_num_eq_p (x, y)
 #ifdef SCM_BIGDIG
   if (SCM_NINUMP (x))
     {
-      SCM_ASSERT (SCM_NIMP (x) && SCM_BIGP (x), x, SCM_ARG1, s_eq_p);
+      SCM_GASSERT2 (SCM_NIMP (x) && SCM_BIGP (x),
+                   g_eq_p, x, y, SCM_ARG1, s_eq_p);
       if (SCM_INUMP (y))
        return SCM_BOOL_F;
       SCM_ASRTGO (SCM_NIMP (y) && SCM_BIGP (y), bady);
@@ -2697,18 +2725,16 @@ scm_num_eq_p (x, y)
     }
   if (SCM_NINUMP (y))
     {
-#ifndef SCM_RECKLESS
       if (!(SCM_NIMP (y) && SCM_BIGP (y)))
        {
        bady:
-         scm_wta (y, (char *) SCM_ARG2, s_eq_p);
+         SCM_WTA_DISPATCH_2 (g_eq_p, x, y, SCM_ARGn, s_eq_p);
        }
-#endif
       return SCM_BOOL_F;
     }
 #else
-  SCM_ASSERT (SCM_INUMP (x), x, SCM_ARG1, s_eq_p);
-  SCM_ASSERT (SCM_INUMP (y), y, SCM_ARG2, s_eq_p);
+  SCM_GASSERT2 (SCM_INUMP (x), g_eq_p, x, y, SCM_ARG1, s_eq_p);
+  SCM_GASSERT2 (SCM_INUMP (y), g_eq_p, x, y, SCM_ARGn, s_eq_p);
 #endif
 #endif
   return ((long) x == (long) y) ? SCM_BOOL_T : SCM_BOOL_F;
@@ -2716,7 +2742,7 @@ scm_num_eq_p (x, y)
 
 
 
-SCM_PROC1 (s_less_p, "<", scm_tc7_rpsubr, scm_less_p);
+SCM_GPROC1 (s_less_p, "<", scm_tc7_rpsubr, scm_less_p, g_less_p);
 
 SCM
 scm_less_p (x, y)
@@ -2727,13 +2753,11 @@ scm_less_p (x, y)
   if (SCM_NINUMP (x))
     {
 #ifdef SCM_BIGDIG
-#ifndef SCM_RECKLESS
       if (!(SCM_NIMP (x)))
        {
        badx:
-         scm_wta (x, (char *) SCM_ARG1, s_less_p);
+         SCM_WTA_DISPATCH_2 (g_less_p, x, y, SCM_ARG1, s_less_p);
        }
-#endif
       if (SCM_BIGP (x))
        {
          if (SCM_INUMP (y))
@@ -2748,7 +2772,8 @@ scm_less_p (x, y)
        }
       SCM_ASRTGO (SCM_REALP (x), badx);
 #else
-      SCM_ASSERT (SCM_NIMP (x) && SCM_REALP (x), x, SCM_ARG1, s_less_p);
+      SCM_GASSERT2 (SCM_NIMP (x) && SCM_REALP (x),
+                   g_less_p, x, y, SCM_ARG1, s_less_p);
 #endif
       if (SCM_INUMP (y))
        return ((SCM_REALPART (x) < ((double) SCM_INUM (y)))
@@ -2770,21 +2795,17 @@ scm_less_p (x, y)
       SCM_ASRTGO (SCM_NIMP (y), bady);
       if (SCM_BIGP (y))
        return SCM_BIGSIGN (y) ? SCM_BOOL_F : SCM_BOOL_T;
-#ifndef SCM_RECKLESS
       if (!(SCM_REALP (y)))
        {
        bady:
-         scm_wta (y, (char *) SCM_ARG2, s_less_p);
+         SCM_WTA_DISPATCH_2 (g_less_p, x, y, SCM_ARGn, s_less_p);
        }
-#endif
 #else
-#ifndef SCM_RECKLESS
       if (!(SCM_NIMP (y) && SCM_REALP (y)))
        {
        bady:
-         scm_wta (y, (char *) SCM_ARG2, s_less_p);
+         SCM_WTA_DISPATCH_2 (g_less_p, x, y, SCM_ARGn, s_less_p);
        }
-#endif
 #endif
       return ((((double) SCM_INUM (x)) < SCM_REALPART (y))
              ? SCM_BOOL_T
@@ -2794,7 +2815,8 @@ scm_less_p (x, y)
 #ifdef SCM_BIGDIG
   if (SCM_NINUMP (x))
     {
-      SCM_ASSERT (SCM_NIMP (x) && SCM_BIGP (x), x, SCM_ARG1, s_less_p);
+      SCM_GASSERT2 (SCM_NIMP (x) && SCM_BIGP (x),
+                   g_less_p, x, y, SCM_ARG1, s_less_p);
       if (SCM_INUMP (y))
        return SCM_BIGSIGN (x) ? SCM_BOOL_T : SCM_BOOL_F;
       SCM_ASRTGO (SCM_NIMP (y) && SCM_BIGP (y), bady);
@@ -2802,18 +2824,16 @@ scm_less_p (x, y)
     }
   if (SCM_NINUMP (y))
     {
-#ifndef SCM_RECKLESS
       if (!(SCM_NIMP (y) && SCM_BIGP (y)))
        {
        bady:
-         scm_wta (y, (char *) SCM_ARG2, s_less_p);
+         SCM_WTA_DISPATCH_2 (g_less_p, x, y, SCM_ARGn, s_less_p);
        }
-#endif
       return SCM_BIGSIGN (y) ? SCM_BOOL_F : SCM_BOOL_T;
     }
 #else
-  SCM_ASSERT (SCM_INUMP (x), x, SCM_ARG1, s_less_p);
-  SCM_ASSERT (SCM_INUMP (y), y, SCM_ARG2, s_less_p);
+  SCM_GASSERT2 (SCM_INUMP (x), g_less_p, x, y, SCM_ARG1, s_less_p);
+  SCM_GASSERT2 (SCM_INUMP (y), g_less_p, x, y, SCM_ARGn, s_less_p);
 #endif
 #endif
   return ((long) x < (long) y) ? SCM_BOOL_T : SCM_BOOL_F;
@@ -2856,7 +2876,7 @@ scm_geq_p (x, y)
 
 
 
-SCM_PROC (s_zero_p, "zero?", 1, 0, 0, scm_zero_p);
+SCM_GPROC (s_zero_p, "zero?", 1, 0, 0, scm_zero_p, g_zero_p);
 
 SCM
 scm_zero_p (z)
@@ -2869,15 +2889,14 @@ scm_zero_p (z)
       SCM_ASRTGO (SCM_NIMP (z), badz);
       if (SCM_BIGP (z))
        return SCM_BOOL_F;
-#ifndef SCM_RECKLESS
       if (!(SCM_INEXP (z)))
        {
        badz:
-         scm_wta (z, (char *) SCM_ARG1, s_zero_p);
+         SCM_WTA_DISPATCH_1 (g_zero_p, z, SCM_ARG1, s_zero_p);
        }
-#endif
 #else
-      SCM_ASSERT (SCM_NIMP (z) && SCM_INEXP (z), z, SCM_ARG1, s_zero_p);
+      SCM_GASSERT1 (SCM_NIMP (z) && SCM_INEXP (z),
+                   g_zero_p, z, SCM_ARG1, s_zero_p);
 #endif
       return (z == scm_flo0) ? SCM_BOOL_T : SCM_BOOL_F;
     }
@@ -2885,11 +2904,12 @@ scm_zero_p (z)
 #ifdef SCM_BIGDIG
   if (SCM_NINUMP (z))
     {
-      SCM_ASSERT (SCM_NIMP (z) && SCM_BIGP (z), z, SCM_ARG1, s_zero_p);
+      SCM_GASSERT1 (SCM_NIMP (z) && SCM_BIGP (z),
+                   g_zero_p, z, SCM_ARG1, s_zero_p);
       return SCM_BOOL_F;
     }
 #else
-  SCM_ASSERT (SCM_INUMP (z), z, SCM_ARG1, s_zero_p);
+  SCM_GASSERT1 (SCM_INUMP (z), g_zero_p, z, SCM_ARG1, s_zero_p);
 #endif
 #endif
   return (z == SCM_INUM0) ? SCM_BOOL_T : SCM_BOOL_F;
@@ -2897,7 +2917,7 @@ scm_zero_p (z)
 
 
 
-SCM_PROC (s_positive_p, "positive?", 1, 0, 0, scm_positive_p);
+SCM_GPROC (s_positive_p, "positive?", 1, 0, 0, scm_positive_p, g_positive_p);
 
 SCM
 scm_positive_p (x)
@@ -2910,15 +2930,14 @@ scm_positive_p (x)
       SCM_ASRTGO (SCM_NIMP (x), badx);
       if (SCM_BIGP (x))
        return SCM_TYP16 (x) == scm_tc16_bigpos ? SCM_BOOL_T : SCM_BOOL_F;
-#ifndef SCM_RECKLESS
       if (!(SCM_REALP (x)))
        {
        badx:
-         scm_wta (x, (char *) SCM_ARG1, s_positive_p);
+         SCM_WTA_DISPATCH_1 (g_positive_p, x, SCM_ARG1, s_positive_p);
        }
-#endif
 #else
-      SCM_ASSERT (SCM_NIMP (x) && SCM_REALP (x), x, SCM_ARG1, s_positive_p);
+      SCM_GASSERT1 (SCM_NIMP (x) && SCM_REALP (x),
+                   g_positive_p, x, SCM_ARG1, s_positive_p);
 #endif
       return (SCM_REALPART (x) > 0.0) ? SCM_BOOL_T : SCM_BOOL_F;
     }
@@ -2926,11 +2945,12 @@ scm_positive_p (x)
 #ifdef SCM_BIGDIG
   if (SCM_NINUMP (x))
     {
-      SCM_ASSERT (SCM_NIMP (x) && SCM_BIGP (x), x, SCM_ARG1, s_positive_p);
+      SCM_GASSERT1 (SCM_NIMP (x) && SCM_BIGP (x),
+                   g_positive_p, x, SCM_ARG1, s_positive_p);
       return SCM_TYP16 (x) == scm_tc16_bigpos ? SCM_BOOL_T : SCM_BOOL_F;
     }
 #else
-  SCM_ASSERT (SCM_INUMP (x), x, SCM_ARG1, s_positive_p);
+  SCM_GASSERT1 (SCM_INUMP (x), g_positive_p, x, SCM_ARG1, s_positive_p);
 #endif
 #endif
   return (x > SCM_INUM0) ? SCM_BOOL_T : SCM_BOOL_F;
@@ -2938,7 +2958,7 @@ scm_positive_p (x)
 
 
 
-SCM_PROC (s_negative_p, "negative?", 1, 0, 0, scm_negative_p);
+SCM_GPROC (s_negative_p, "negative?", 1, 0, 0, scm_negative_p, g_negative_p);
 
 SCM
 scm_negative_p (x)
@@ -2951,15 +2971,14 @@ scm_negative_p (x)
       SCM_ASRTGO (SCM_NIMP (x), badx);
       if (SCM_BIGP (x))
        return SCM_TYP16 (x) == scm_tc16_bigpos ? SCM_BOOL_F : SCM_BOOL_T;
-#ifndef SCM_RECKLESS
       if (!(SCM_REALP (x)))
        {
        badx:
-         scm_wta (x, (char *) SCM_ARG1, s_negative_p);
+         SCM_WTA_DISPATCH_1 (g_negative_p, x, SCM_ARG1, s_negative_p);
        }
-#endif
 #else
-      SCM_ASSERT (SCM_NIMP (x) && SCM_REALP (x), x, SCM_ARG1, s_negative_p);
+      SCM_GASSERT1 (SCM_NIMP (x) && SCM_REALP (x),
+                   g_negative_p, x, SCM_ARG1, s_negative_p);
 #endif
       return (SCM_REALPART (x) < 0.0) ? SCM_BOOL_T : SCM_BOOL_F;
     }
@@ -2967,18 +2986,19 @@ scm_negative_p (x)
 #ifdef SCM_BIGDIG
   if (SCM_NINUMP (x))
     {
-      SCM_ASSERT (SCM_NIMP (x) && SCM_BIGP (x), x, SCM_ARG1, s_negative_p);
+      SCM_GASSERT1 (SCM_NIMP (x) && SCM_BIGP (x),
+                   g_negative_p, x, SCM_ARG1, s_negative_p);
       return (SCM_TYP16 (x) == scm_tc16_bigneg) ? SCM_BOOL_T : SCM_BOOL_F;
     }
 #else
-  SCM_ASSERT (SCM_INUMP (x), x, SCM_ARG1, s_negative_p);
+  SCM_GASSERT1 (SCM_INUMP (x), g_negative_p, x, SCM_ARG1, s_negative_p);
 #endif
 #endif
   return (x < SCM_INUM0) ? SCM_BOOL_T : SCM_BOOL_F;
 }
 
 
-SCM_PROC1 (s_max, "max", scm_tc7_asubr, scm_max);
+SCM_GPROC1 (s_max, "max", scm_tc7_asubr, scm_max, g_max);
 
 SCM
 scm_max (x, y)
@@ -2990,20 +3010,20 @@ scm_max (x, y)
 #endif
   if (SCM_UNBNDP (y))
     {
-#ifndef SCM_RECKLESS
-      if (!(SCM_NUMBERP (x)))
-       {
-       badx:
-         scm_wta (x, (char *) SCM_ARG1, s_max);
-       }
-#endif
+      SCM_GASSERT0 (!SCM_UNBNDP (x),
+                   g_max, scm_makfrom0str (s_max), SCM_WNA, 0);
+      SCM_GASSERT1 (SCM_NUMBERP (x), g_max, x, SCM_ARG1, s_max);
       return x;
     }
 #ifdef SCM_FLOATS
   if (SCM_NINUMP (x))
     {
 #ifdef SCM_BIGDIG
-      SCM_ASRTGO (SCM_NIMP (x), badx);
+      if (!SCM_NIMP (x))
+       {
+       badx2:
+         SCM_WTA_DISPATCH_2 (g_max, x, y, SCM_ARG1, s_max);
+       }
       if (SCM_BIGP (x))
        {
          if (SCM_INUMP (y))
@@ -3015,9 +3035,10 @@ scm_max (x, y)
          z = scm_big2dbl (x);
          return (z < SCM_REALPART (y)) ? y : scm_makdbl (z, 0.0);
        }
-      SCM_ASRTGO (SCM_REALP (x), badx);
+      SCM_ASRTGO (SCM_REALP (x), badx2);
 #else
-      SCM_ASSERT (SCM_NIMP (x) && SCM_REALP (x), x, SCM_ARG1, s_max);
+      SCM_GASSERT2 (SCM_NIMP (x) && SCM_REALP (x),
+                   g_max, x, y, SCM_ARG1, s_max);
 #endif
       if (SCM_INUMP (y))
        return ((SCM_REALPART (x) < (z = SCM_INUM (y)))
@@ -3041,21 +3062,17 @@ scm_max (x, y)
       SCM_ASRTGO (SCM_NIMP (y), bady);
       if (SCM_BIGP (y))
        return SCM_BIGSIGN (y) ? x : y;
-#ifndef SCM_RECKLESS
       if (!(SCM_REALP (y)))
        {
        bady:
-         scm_wta (y, (char *) SCM_ARG2, s_max);
+         SCM_WTA_DISPATCH_2 (g_max, x, y, SCM_ARGn, s_max);
        }
-#endif
 #else
-#ifndef SCM_RECKLESS
       if (!(SCM_NIMP (y) && SCM_REALP (y)))
        {
        bady:
-         scm_wta (y, (char *) SCM_ARG2, s_max);
+         SCM_WTA_DISPATCH_2 (g_max, x, y, SCM_ARGn, s_max);
        }
-#endif
 #endif
       return (((z = SCM_INUM (x)) < SCM_REALPART (y))
              ? y
@@ -3065,7 +3082,8 @@ scm_max (x, y)
 #ifdef SCM_BIGDIG
   if (SCM_NINUMP (x))
     {
-      SCM_ASSERT (SCM_NIMP (x) && SCM_BIGP (x), x, SCM_ARG1, s_max);
+      SCM_GASSERT2 (SCM_NIMP (x) && SCM_BIGP (x),
+                   g_max, x, y, SCM_ARG1, s_max);
       if (SCM_INUMP (y))
        return SCM_BIGSIGN (x) ? y : x;
       SCM_ASRTGO (SCM_NIMP (y) && SCM_BIGP (y), bady);
@@ -3073,18 +3091,16 @@ scm_max (x, y)
     }
   if (SCM_NINUMP (y))
     {
-#ifndef SCM_RECKLESS
       if (!(SCM_NIMP (y) && SCM_BIGP (y)))
        {
        bady:
-         scm_wta (y, (char *) SCM_ARG2, s_max);
+         SCM_WTA_DISPATCH_2 (g_max, x, y, SCM_ARGn, s_max);
        }
-#endif
       return SCM_BIGSIGN (y) ? x : y;
     }
 #else
-  SCM_ASSERT (SCM_INUMP (x), x, SCM_ARG1, s_max);
-  SCM_ASSERT (SCM_INUMP (y), y, SCM_ARG2, s_max);
+  SCM_GASSERT2 (SCM_INUMP (x), g_max, x, y, SCM_ARG1, s_max);
+  SCM_GASSERT2 (SCM_INUMP (y), g_max, x, y, SCM_ARGn, s_max);
 #endif
 #endif
   return ((long) x < (long) y) ? y : x;
@@ -3093,7 +3109,7 @@ scm_max (x, y)
 
 
 
-SCM_PROC1 (s_min, "min", scm_tc7_asubr, scm_min);
+SCM_GPROC1 (s_min, "min", scm_tc7_asubr, scm_min, g_min);
 
 SCM
 scm_min (x, y)
@@ -3105,20 +3121,20 @@ scm_min (x, y)
 #endif
   if (SCM_UNBNDP (y))
     {
-#ifndef SCM_RECKLESS
-      if (!(SCM_NUMBERP (x)))
-       {
-       badx:
-         scm_wta (x, (char *) SCM_ARG1, s_min);
-       }
-#endif
+      SCM_GASSERT0 (!SCM_UNBNDP (x),
+                   g_min, scm_makfrom0str (s_min), SCM_WNA, 0);
+      SCM_GASSERT1 (SCM_NUMBERP (x), g_min, x, SCM_ARG1, s_min);
       return x;
     }
 #ifdef SCM_FLOATS
   if (SCM_NINUMP (x))
     {
 #ifdef SCM_BIGDIG
-      SCM_ASRTGO (SCM_NIMP (x), badx);
+      if (!(SCM_NIMP (x)))
+       {
+       badx2:
+         SCM_WTA_DISPATCH_2 (g_min, x, y, SCM_ARG1, s_min);
+       }
       if (SCM_BIGP (x))
        {
          if (SCM_INUMP (y))
@@ -3130,9 +3146,10 @@ scm_min (x, y)
          z = scm_big2dbl (x);
          return (z > SCM_REALPART (y)) ? y : scm_makdbl (z, 0.0);
        }
-      SCM_ASRTGO (SCM_REALP (x), badx);
+      SCM_ASRTGO (SCM_REALP (x), badx2);
 #else
-      SCM_ASSERT (SCM_NIMP (x) && SCM_REALP (x), x, SCM_ARG1, s_min);
+      SCM_GASSERT2 (SCM_NIMP (x) && SCM_REALP (x),
+                   g_min, x, y, SCM_ARG1, s_min);
 #endif
       if (SCM_INUMP (y))
        return ((SCM_REALPART (x) > (z = SCM_INUM (y)))
@@ -3156,21 +3173,17 @@ scm_min (x, y)
       SCM_ASRTGO (SCM_NIMP (y), bady);
       if (SCM_BIGP (y))
        return SCM_BIGSIGN (y) ? y : x;
-#ifndef SCM_RECKLESS
       if (!(SCM_REALP (y)))
        {
        bady:
-         scm_wta (y, (char *) SCM_ARG2, s_min);
+         SCM_WTA_DISPATCH_2 (g_min, x, y, SCM_ARGn, s_min);
        }
-#endif
 #else
-#ifndef SCM_RECKLESS
       if (!(SCM_NIMP (y) && SCM_REALP (y)))
        {
        bady:
-         scm_wta (y, (char *) SCM_ARG2, s_min);
+         SCM_WTA_DISPATCH_2 (g_min, x, y, SCM_ARGn, s_min);
        }
-#endif
 #endif
       return (((z = SCM_INUM (x)) > SCM_REALPART (y))
              ? y
@@ -3180,7 +3193,8 @@ scm_min (x, y)
 #ifdef SCM_BIGDIG
   if (SCM_NINUMP (x))
     {
-      SCM_ASSERT (SCM_NIMP (x) && SCM_BIGP (x), x, SCM_ARG1, s_min);
+      SCM_GASSERT2 (SCM_NIMP (x) && SCM_BIGP (x),
+                   g_min, x, y, SCM_ARG1, s_min);
       if (SCM_INUMP (y))
        return SCM_BIGSIGN (x) ? x : y;
       SCM_ASRTGO (SCM_NIMP (y) && SCM_BIGP (y), bady);
@@ -3188,18 +3202,16 @@ scm_min (x, y)
     }
   if (SCM_NINUMP (y))
     {
-#ifndef SCM_RECKLESS
       if (!(SCM_NIMP (y) && SCM_BIGP (y)))
        {
        bady:
-         scm_wta (y, (char *) SCM_ARG2, s_min);
+         SCM_WTA_DISPATCH_2 (g_min, x, y, SCM_ARGn, s_min);
        }
-#endif
       return SCM_BIGSIGN (y) ? y : x;
     }
 #else
-  SCM_ASSERT (SCM_INUMP (x), x, SCM_ARG1, s_min);
-  SCM_ASSERT (SCM_INUMP (y), y, SCM_ARG2, s_min);
+  SCM_GASSERT2 (SCM_INUMP (x), g_min, x, y, SCM_ARG1, s_min);
+  SCM_GASSERT2 (SCM_INUMP (y), g_min, x, y, SCM_ARGn, s_min);
 #endif
 #endif
   return ((long) x > (long) y) ? y : x;
@@ -3208,7 +3220,7 @@ scm_min (x, y)
 
 
 
-SCM_PROC1 (s_sum, "+", scm_tc7_asubr, scm_sum);
+SCM_GPROC1 (s_sum, "+", scm_tc7_asubr, scm_sum, g_sum);
 
 SCM
 scm_sum (x, y)
@@ -3219,13 +3231,7 @@ scm_sum (x, y)
     {
       if (SCM_UNBNDP (x))
        return SCM_INUM0;
-#ifndef SCM_RECKLESS
-      if (!(SCM_NUMBERP (x)))
-       {
-       badx:
-         scm_wta (x, (char *) SCM_ARG1, s_sum);
-       }
-#endif
+      SCM_GASSERT1 (SCM_NUMBERP (x), g_sum, x, SCM_ARG1, s_sum);
       return x;
     }
 #ifdef SCM_FLOATS
@@ -3233,7 +3239,11 @@ scm_sum (x, y)
     {
       SCM t;
 #ifdef SCM_BIGDIG
-      SCM_ASRTGO (SCM_NIMP (x), badx);
+      if (!SCM_NIMP (x))
+       {
+       badx2:
+         SCM_WTA_DISPATCH_2 (g_sum, x, y, SCM_ARG1, s_sum);
+       }
       if (SCM_BIGP (x))
        {
          if (SCM_INUMP (y))
@@ -3261,9 +3271,9 @@ scm_sum (x, y)
          return scm_makdbl (scm_big2dbl (x) + SCM_REALPART (y),
                             SCM_CPLXP (y) ? SCM_IMAG (y) : 0.0);
        }
-      SCM_ASRTGO (SCM_INEXP (x), badx);
+      SCM_ASRTGO (SCM_INEXP (x), badx2);
 #else
-      SCM_ASRTGO (SCM_NIMP (x) && SCM_INEXP (x), badx);
+      SCM_ASRTGO (SCM_NIMP (x) && SCM_INEXP (x), badx2);
 #endif
       if (SCM_INUMP (y))
        {
@@ -3281,21 +3291,17 @@ scm_sum (x, y)
          y = t;
          goto bigreal;
        }
-#ifndef SCM_RECKLESS
       else if (!(SCM_INEXP (y)))
        {
        bady:
-         scm_wta (y, (char *) SCM_ARG2, s_sum);
+         SCM_WTA_DISPATCH_2 (g_sum, x, y, SCM_ARGn, s_sum);
        }
-#endif
 #else
-#ifndef SCM_RECKLESS
       if (!(SCM_NIMP (y) && SCM_INEXP (y)))
        {
        bady:
-         scm_wta (y, (char *) SCM_ARG2, s_sum);
+         SCM_WTA_DISPATCH_2 (g_sum, x, y, SCM_ARGn, s_sum);
        }
-#endif
 #endif
       {
        double i = 0.0;
@@ -3341,7 +3347,7 @@ scm_sum (x, y)
   if (SCM_NINUMP (x))
     {
       SCM t;
-      SCM_ASRTGO (SCM_NIMP (x) && SCM_BIGP (x), badx);
+      SCM_ASRTGO (SCM_NIMP (x) && SCM_BIGP (x), badx2);
       if (SCM_INUMP (y))
        {
          t = x;
@@ -3361,13 +3367,11 @@ scm_sum (x, y)
     }
   if (SCM_NINUMP (y))
     {
-#ifndef SCM_RECKLESS
       if (!(SCM_NIMP (y) && SCM_BIGP (y)))
        {
        bady:
-         scm_wta (y, (char *) SCM_ARG2, s_sum);
+         SCM_WTA_DISPATCH_2 (g_sum, x, y, SCM_ARGn, s_sum);
        }
-#endif
     intbig:
       {
 #ifndef SCM_DIGSTOOBIG
@@ -3381,8 +3385,8 @@ scm_sum (x, y)
       }
     }
 #else
-  SCM_ASRTGO (SCM_INUMP (x), badx);
-  SCM_ASSERT (SCM_INUMP (y), y, SCM_ARG2, s_sum);
+  SCM_ASRTGO (SCM_INUMP (x), badx2);
+  SCM_GASSERT2 (SCM_INUMP (y), g_sum, x, y, SCM_ARGn, s_sum);
 #endif
 #endif
   x = SCM_INUM (x) + SCM_INUM (y);
@@ -3403,7 +3407,7 @@ scm_sum (x, y)
 
 
 
-SCM_PROC1 (s_difference, "-", scm_tc7_asubr, scm_difference);
+SCM_GPROC1 (s_difference, "-", scm_tc7_asubr, scm_difference, g_difference);
 
 SCM
 scm_difference (x, y)
@@ -3413,13 +3417,21 @@ scm_difference (x, y)
 #ifdef SCM_FLOATS
   if (SCM_NINUMP (x))
     {
-#ifndef SCM_RECKLESS
       if (!(SCM_NIMP (x)))
        {
-       badx:
-         scm_wta (x, (char *) SCM_ARG1, s_difference);
+         if (SCM_UNBNDP (y))
+           {
+             SCM_GASSERT0 (!SCM_UNBNDP (x), g_difference,
+                           scm_makfrom0str (s_difference), SCM_WNA, 0);
+           badx:
+             SCM_WTA_DISPATCH_1 (g_difference, x, SCM_ARG1, s_difference);
+           }
+         else
+           {
+           badx2:
+             SCM_WTA_DISPATCH_2 (g_difference, x, y, SCM_ARG1, s_difference);
+           }
        }
-#endif
       if (SCM_UNBNDP (y))
        {
 #ifdef SCM_BIGDIG
@@ -3454,13 +3466,13 @@ scm_difference (x, y)
          return scm_makdbl (scm_big2dbl (x) - SCM_REALPART (y),
                             SCM_CPLXP (y) ? -SCM_IMAG (y) : 0.0);
        }
-      SCM_ASRTGO (SCM_INEXP (x), badx);
+      SCM_ASRTGO (SCM_INEXP (x), badx2);
       if (SCM_BIGP (y))
        return scm_makdbl (SCM_REALPART (x) - scm_big2dbl (y),
                           SCM_CPLXP (x) ? SCM_IMAG (x) : 0.0);
       SCM_ASRTGO (SCM_INEXP (y), bady);
 #else
-      SCM_ASRTGO (SCM_INEXP (x), badx);
+      SCM_ASRTGO (SCM_INEXP (x), badx2);
       SCM_ASRTGO (SCM_NIMP (y) && SCM_INEXP (y), bady);
 #endif
       if (SCM_CPLXP (x))
@@ -3497,21 +3509,17 @@ scm_difference (x, y)
                             y, 0x0100);
 #endif
        }
-#ifndef SCM_RECKLESS
       if (!(SCM_INEXP (y)))
        {
        bady:
-         scm_wta (y, (char *) SCM_ARG2, s_difference);
+         SCM_WTA_DISPATCH_2 (g_difference, x, y, SCM_ARGn, s_difference);
        }
-#endif
 #else
-#ifndef SCM_RECKLESS
       if (!(SCM_NIMP (y) && SCM_INEXP (y)))
        {
        bady:
-         scm_wta (y, (char *) SCM_ARG2, s_difference);
+         SCM_WTA_DISPATCH_2 (g_difference, x, y, SCM_ARGn, s_difference);
        }
-#endif
 #endif
       return scm_makdbl (SCM_INUM (x) - SCM_REALPART (y),
                         SCM_CPLXP (y) ? -SCM_IMAG (y) : 0.0);
@@ -3520,7 +3528,8 @@ scm_difference (x, y)
 #ifdef SCM_BIGDIG
   if (SCM_NINUMP (x))
     {
-      SCM_ASSERT (SCM_NIMP (x) && SCM_BIGP (x), x, SCM_ARG1, s_difference);
+      SCM_GASSERT2 (SCM_NIMP (x) && SCM_BIGP (x),
+                   g_difference, x, y, SCM_ARG1, s_difference);
       if (SCM_UNBNDP (y))
        {
          x = scm_copybig (x, !SCM_BIGSIGN (x));
@@ -3555,13 +3564,11 @@ scm_difference (x, y)
     }
   if (SCM_NINUMP (y))
     {
-#ifndef SCM_RECKLESS
       if (!(SCM_NIMP (y) && SCM_BIGP (y)))
        {
        bady:
-         scm_wta (y, (char *) SCM_ARG2, s_difference);
+         SCM_WTA_DISPATCH_2 (g_difference, x, y, SCM_ARGn, s_difference);
        }
-#endif
       {
 #ifndef SCM_DIGSTOOBIG
        long z = scm_pseudolong (SCM_INUM (x));
@@ -3576,13 +3583,13 @@ scm_difference (x, y)
       }
     }
 #else
-  SCM_ASSERT (SCM_INUMP (x), x, SCM_ARG1, s_difference);
+  SCM_GASSERT2 (SCM_INUMP (x), g_difference, x, y, SCM_ARG1, s_difference);
   if (SCM_UNBNDP (y))
     {
       x = -SCM_INUM (x);
       goto checkx;
     }
-  SCM_ASSERT (SCM_INUMP (y), y, SCM_ARG2, s_difference);
+  SCM_GASSERT2 (SCM_INUMP (y), g_difference, x, y, SCM_ARGn, s_difference);
 #endif
 #endif
   x = SCM_INUM (x) - SCM_INUM (y);
@@ -3604,7 +3611,7 @@ scm_difference (x, y)
 
 
 
-SCM_PROC1 (s_product, "*", scm_tc7_asubr, scm_product);
+SCM_GPROC1 (s_product, "*", scm_tc7_asubr, scm_product, g_product);
 
 SCM
 scm_product (x, y)
@@ -3615,13 +3622,7 @@ scm_product (x, y)
     {
       if (SCM_UNBNDP (x))
        return SCM_MAKINUM (1L);
-#ifndef SCM_RECKLESS
-      if (!(SCM_NUMBERP (x)))
-       {
-       badx:
-         scm_wta (x, (char *) SCM_ARG1, s_product);
-       }
-#endif
+      SCM_GASSERT1 (SCM_NUMBERP (x), g_product, x, SCM_ARG1, s_product);
       return x;
     }
 #ifdef SCM_FLOATS
@@ -3629,7 +3630,11 @@ scm_product (x, y)
     {
       SCM t;
 #ifdef SCM_BIGDIG
-      SCM_ASRTGO (SCM_NIMP (x), badx);
+      if (!SCM_NIMP (x))
+       {
+       badx2:
+         SCM_WTA_DISPATCH_2 (g_product, x, y, SCM_ARG1, s_product);
+       }
       if (SCM_BIGP (x))
        {
          if (SCM_INUMP (y))
@@ -3652,9 +3657,9 @@ scm_product (x, y)
                               SCM_CPLXP (y) ? bg * SCM_IMAG (y) : 0.0);
          }
        }
-      SCM_ASRTGO (SCM_INEXP (x), badx);
+      SCM_ASRTGO (SCM_INEXP (x), badx2);
 #else
-      SCM_ASRTGO (SCM_NIMP (x) && SCM_INEXP (x), badx);
+      SCM_ASRTGO (SCM_NIMP (x) && SCM_INEXP (x), badx2);
 #endif
       if (SCM_INUMP (y))
        {
@@ -3672,21 +3677,17 @@ scm_product (x, y)
          y = t;
          goto bigreal;
        }
-#ifndef SCM_RECKLESS
       else if (!(SCM_INEXP (y)))
        {
        bady:
-         scm_wta (y, (char *) SCM_ARG2, s_product);
+         SCM_WTA_DISPATCH_2 (g_product, x, y, SCM_ARGn, s_product);
        }
-#endif
 #else
-#ifndef SCM_RECKLESS
       if (!(SCM_NIMP (y) && SCM_INEXP (y)))
        {
        bady:
-         scm_wta (y, (char *) SCM_ARG2, s_product);
+         SCM_WTA_DISPATCH_2 (g_product, x, y, SCM_ARGn, s_product);
        }
-#endif
 #endif
       if (SCM_CPLXP (x))
        {
@@ -3742,7 +3743,7 @@ scm_product (x, y)
 #ifdef SCM_BIGDIG
   if (SCM_NINUMP (x))
     {
-      SCM_ASRTGO (SCM_NIMP (x) && SCM_BIGP (x), badx);
+      SCM_ASRTGO (SCM_NIMP (x) && SCM_BIGP (x), badx2);
       if (SCM_INUMP (y))
        {
          SCM t = x;
@@ -3757,13 +3758,11 @@ scm_product (x, y)
     }
   if (SCM_NINUMP (y))
     {
-#ifndef SCM_RECKLESS
       if (!(SCM_NIMP (y) && SCM_BIGP (y)))
        {
        bady:
-         scm_wta (y, (char *) SCM_ARG2, s_product);
+         SCM_WTA_DISPATCH_2 (g_product, x, y, SCM_ARGn, s_product);
        }
-#endif
     intbig:
       if (SCM_INUM0 == x)
        return x;
@@ -3785,8 +3784,8 @@ scm_product (x, y)
       }
     }
 #else
-  SCM_ASRTGO (SCM_INUMP (x), badx);
-  SCM_ASSERT (SCM_INUMP (y), y, SCM_ARG2, s_product);
+  SCM_ASRTGO (SCM_INUMP (x), badx2);
+  SCM_GASSERT (SCM_INUMP (y), g_product, x, y, SCM_ARGn, s_product);
 #endif
 #endif
   {
@@ -3849,7 +3848,7 @@ scm_num2dbl (a, why)
 }
 
 
-SCM_PROC1 (s_divide, "/", scm_tc7_asubr, scm_divide);
+SCM_GPROC1 (s_divide, "/", scm_tc7_asubr, scm_divide, g_divide);
 
 SCM
 scm_divide (x, y)
@@ -3860,13 +3859,21 @@ scm_divide (x, y)
   double d, r, i, a;
   if (SCM_NINUMP (x))
     {
-#ifndef SCM_RECKLESS
       if (!(SCM_NIMP (x)))
        {
-       badx:
-         scm_wta (x, (char *) SCM_ARG1, s_divide);
+         if (SCM_UNBNDP (y))
+           {
+             SCM_GASSERT0 (!SCM_UNBNDP (x),
+                           g_divide, scm_makfrom0str (s_divide), SCM_WNA, 0);
+           badx:
+             SCM_WTA_DISPATCH_1 (g_divide, x, SCM_ARG1, s_divide);
+           }
+         else
+           {
+           badx2:
+             SCM_WTA_DISPATCH_2 (g_divide, x, y, SCM_ARG1, s_divide);
+           }
        }
-#endif
       if (SCM_UNBNDP (y))
        {
 #ifdef SCM_BIGDIG
@@ -3936,7 +3943,7 @@ scm_divide (x, y)
          goto complex_div;
        }
 #endif
-      SCM_ASRTGO (SCM_INEXP (x), badx);
+      SCM_ASRTGO (SCM_INEXP (x), badx2);
       if (SCM_INUMP (y))
        {
          d = SCM_INUM (y);
@@ -3981,21 +3988,17 @@ scm_divide (x, y)
       SCM_ASRTGO (SCM_NIMP (y), bady);
       if (SCM_BIGP (y))
        return scm_makdbl (SCM_INUM (x) / scm_big2dbl (y), 0.0);
-#ifndef SCM_RECKLESS
       if (!(SCM_INEXP (y)))
        {
        bady:
-         scm_wta (y, (char *) SCM_ARG2, s_divide);
+         SCM_WTA_DISPATCH_2 (g_divide, x, y, SCM_ARGn, s_divide);
        }
-#endif
 #else
-#ifndef SCM_RECKLESS
       if (!(SCM_NIMP (y) && SCM_INEXP (y)))
        {
        bady:
-         scm_wta (y, (char *) SCM_ARG2, s_divide);
+         SCM_WTA_DISPATCH_2 (g_divide, x, y, SCM_ARGn, s_divide);
        }
-#endif
 #endif
       if (SCM_REALP (y))
        return scm_makdbl (SCM_INUM (x) / SCM_REALPART (y), 0.0);
@@ -4011,7 +4014,8 @@ scm_divide (x, y)
   if (SCM_NINUMP (x))
     {
       SCM z;
-      SCM_ASSERT (SCM_NIMP (x) && SCM_BIGP (x), x, SCM_ARG1, s_divide);
+      SCM_GASSERT2 (SCM_NIMP (x) && SCM_BIGP (x),
+                   g_divide, x, y, SCM_ARG1, s_divide);
       if (SCM_UNBNDP (y))
        goto ov;
       if (SCM_INUMP (y))
@@ -4065,24 +4069,22 @@ scm_divide (x, y)
     }
   if (SCM_NINUMP (y))
     {
-#ifndef SCM_RECKLESS
       if (!(SCM_NIMP (y) && SCM_BIGP (y)))
        {
        bady:
-         scm_wta (y, (char *) SCM_ARG2, s_divide);
+         SCM_WTA_DISPATCH_2 (g_divide, x, y, SCM_ARGn, s_divide);
        }
-#endif
       goto ov;
     }
 #else
-  SCM_ASSERT (SCM_INUMP (x), x, SCM_ARG1, s_divide);
+  SCM_GASSERT2 (SCM_INUMP (x), g_divide, x, y, SCM_ARG1, s_divide);
   if (SCM_UNBNDP (y))
     {
       if ((SCM_MAKINUM (1L) == x) || (SCM_MAKINUM (-1L) == x))
        return x;
       goto ov;
     }
-  SCM_ASSERT (SCM_INUMP (y), y, SCM_ARG2, s_divide);
+  SCM_GASSERT2 (SCM_INUMP (y), g_divide, x, y, SCM_ARGn, s_divide);
 #endif
 #endif
   {
@@ -4110,7 +4112,7 @@ scm_divide (x, y)
 
 
 #ifdef SCM_FLOATS
-SCM_PROC1 (s_asinh, "$asinh", scm_tc7_cxr, (SCM (*)()) scm_asinh);
+SCM_GPROC1 (s_asinh, "$asinh", scm_tc7_cxr, (SCM (*)()) scm_asinh, g_asinh);
 
 double
 scm_asinh (x)
@@ -4122,7 +4124,7 @@ scm_asinh (x)
 
 
 
-SCM_PROC1 (s_acosh, "$acosh", scm_tc7_cxr, (SCM (*)()) scm_acosh);
+SCM_GPROC1 (s_acosh, "$acosh", scm_tc7_cxr, (SCM (*)()) scm_acosh, g_acosh);
 
 double
 scm_acosh (x)
@@ -4134,7 +4136,7 @@ scm_acosh (x)
 
 
 
-SCM_PROC1 (s_atanh, "$atanh", scm_tc7_cxr, (SCM (*)()) scm_atanh);
+SCM_GPROC1 (s_atanh, "$atanh", scm_tc7_cxr, (SCM (*)()) scm_atanh, g_atanh);
 
 double
 scm_atanh (x)
@@ -4146,7 +4148,7 @@ scm_atanh (x)
 
 
 
-SCM_PROC1 (s_truncate, "truncate", scm_tc7_cxr, (SCM (*)()) scm_truncate);
+SCM_GPROC1 (s_truncate, "truncate", scm_tc7_cxr, (SCM (*)()) scm_truncate, g_truncate);
 
 double
 scm_truncate (x)
@@ -4159,7 +4161,7 @@ scm_truncate (x)
 
 
 
-SCM_PROC1 (s_round, "round", scm_tc7_cxr, (SCM (*)()) scm_round);
+SCM_GPROC1 (s_round, "round", scm_tc7_cxr, (SCM (*)()) scm_round, g_round);
 
 double
 scm_round (x)
@@ -4174,7 +4176,7 @@ scm_round (x)
 
 
 
-SCM_PROC1 (s_exact_to_inexact, "exact->inexact", scm_tc7_cxr, (SCM (*)()) scm_exact_to_inexact);
+SCM_GPROC1 (s_exact_to_inexact, "exact->inexact", scm_tc7_cxr, (SCM (*)()) scm_exact_to_inexact, g_exact_to_inexact);
 
 double
 scm_exact_to_inexact (z)
@@ -4184,21 +4186,21 @@ scm_exact_to_inexact (z)
 }
 
 
-SCM_PROC1 (s_i_floor, "floor", scm_tc7_cxr, (SCM (*)()) floor);
-SCM_PROC1 (s_i_ceil, "ceiling", scm_tc7_cxr, (SCM (*)()) ceil);
-SCM_PROC1 (s_i_sqrt, "$sqrt", scm_tc7_cxr, (SCM (*)()) sqrt);
-SCM_PROC1 (s_i_abs, "$abs", scm_tc7_cxr, (SCM (*)()) fabs);
-SCM_PROC1 (s_i_exp, "$exp", scm_tc7_cxr, (SCM (*)()) exp);
-SCM_PROC1 (s_i_log, "$log", scm_tc7_cxr, (SCM (*)()) log);
-SCM_PROC1 (s_i_sin, "$sin", scm_tc7_cxr, (SCM (*)()) sin);
-SCM_PROC1 (s_i_cos, "$cos", scm_tc7_cxr, (SCM (*)()) cos);
-SCM_PROC1 (s_i_tan, "$tan", scm_tc7_cxr, (SCM (*)()) tan);
-SCM_PROC1 (s_i_asin, "$asin", scm_tc7_cxr, (SCM (*)()) asin);
-SCM_PROC1 (s_i_acos, "$acos", scm_tc7_cxr, (SCM (*)()) acos);
-SCM_PROC1 (s_i_atan, "$atan", scm_tc7_cxr, (SCM (*)()) atan);
-SCM_PROC1 (s_i_sinh, "$sinh", scm_tc7_cxr, (SCM (*)()) sinh);
-SCM_PROC1 (s_i_cosh, "$cosh", scm_tc7_cxr, (SCM (*)()) cosh);
-SCM_PROC1 (s_i_tanh, "$tanh", scm_tc7_cxr, (SCM (*)()) tanh);
+SCM_GPROC1 (s_i_floor, "floor", scm_tc7_cxr, (SCM (*)()) floor, g_i_floor);
+SCM_GPROC1 (s_i_ceil, "ceiling", scm_tc7_cxr, (SCM (*)()) ceil, g_i_ceil);
+SCM_GPROC1 (s_i_sqrt, "$sqrt", scm_tc7_cxr, (SCM (*)()) sqrt, g_i_sqrt);
+SCM_GPROC1 (s_i_abs, "$abs", scm_tc7_cxr, (SCM (*)()) fabs, g_i_abs);
+SCM_GPROC1 (s_i_exp, "$exp", scm_tc7_cxr, (SCM (*)()) exp, g_i_exp);
+SCM_GPROC1 (s_i_log, "$log", scm_tc7_cxr, (SCM (*)()) log, g_i_log);
+SCM_GPROC1 (s_i_sin, "$sin", scm_tc7_cxr, (SCM (*)()) sin, g_i_sin);
+SCM_GPROC1 (s_i_cos, "$cos", scm_tc7_cxr, (SCM (*)()) cos, g_i_cos);
+SCM_GPROC1 (s_i_tan, "$tan", scm_tc7_cxr, (SCM (*)()) tan, g_i_tan);
+SCM_GPROC1 (s_i_asin, "$asin", scm_tc7_cxr, (SCM (*)()) asin, g_i_asin);
+SCM_GPROC1 (s_i_acos, "$acos", scm_tc7_cxr, (SCM (*)()) acos, g_i_acos);
+SCM_GPROC1 (s_i_atan, "$atan", scm_tc7_cxr, (SCM (*)()) atan, g_i_atan);
+SCM_GPROC1 (s_i_sinh, "$sinh", scm_tc7_cxr, (SCM (*)()) sinh, g_i_sinh);
+SCM_GPROC1 (s_i_cosh, "$cosh", scm_tc7_cxr, (SCM (*)()) cosh, g_i_cosh);
+SCM_GPROC1 (s_i_tanh, "$tanh", scm_tc7_cxr, (SCM (*)()) tanh, g_i_tanh);
 
 struct dpair
 {
@@ -4324,7 +4326,7 @@ scm_make_polar (z1, z2)
 
 
 
-SCM_PROC (s_real_part, "real-part", 1, 0, 0, scm_real_part);
+SCM_GPROC (s_real_part, "real-part", 1, 0, 0, scm_real_part, g_real_part);
 
 SCM
 scm_real_part (z)
@@ -4336,15 +4338,14 @@ scm_real_part (z)
       SCM_ASRTGO (SCM_NIMP (z), badz);
       if (SCM_BIGP (z))
        return z;
-#ifndef SCM_RECKLESS
       if (!(SCM_INEXP (z)))
        {
        badz:
-         scm_wta (z, (char *) SCM_ARG1, s_real_part);
+         SCM_WTA_DISPATCH_1 (g_real_part, z, SCM_ARG1, s_real_part);
        }
-#endif
 #else
-      SCM_ASSERT (SCM_NIMP (z) && SCM_INEXP (z), z, SCM_ARG1, s_real_part);
+      SCM_GASSERT1 (SCM_NIMP (z) && SCM_INEXP (z),
+                   g_real_part, z, SCM_ARG1, s_real_part);
 #endif
       if (SCM_CPLXP (z))
        return scm_makdbl (SCM_REAL (z), 0.0);
@@ -4354,7 +4355,7 @@ scm_real_part (z)
 
 
 
-SCM_PROC (s_imag_part, "imag-part", 1, 0, 0, scm_imag_part);
+SCM_GPROC (s_imag_part, "imag-part", 1, 0, 0, scm_imag_part, g_imag_part);
 
 SCM
 scm_imag_part (z)
@@ -4366,15 +4367,14 @@ scm_imag_part (z)
   SCM_ASRTGO (SCM_NIMP (z), badz);
   if (SCM_BIGP (z))
     return SCM_INUM0;
-#ifndef SCM_RECKLESS
   if (!(SCM_INEXP (z)))
     {
     badz:
-      scm_wta (z, (char *) SCM_ARG1, s_imag_part);
+      SCM_WTA_DISPATCH_1 (g_imag_part, z, SCM_ARG1, s_imag_part);
     }
-#endif
 #else
-  SCM_ASSERT (SCM_NIMP (z) && SCM_INEXP (z), z, SCM_ARG1, s_imag_part);
+  SCM_GASSERT1 (SCM_NIMP (z) && SCM_INEXP (z),
+               g_imag_part, z, SCM_ARG1, s_imag_part);
 #endif
   if (SCM_CPLXP (z))
     return scm_makdbl (SCM_IMAG (z), 0.0);
@@ -4383,7 +4383,7 @@ scm_imag_part (z)
 
 
 
-SCM_PROC (s_magnitude, "magnitude", 1, 0, 0, scm_magnitude);
+SCM_GPROC (s_magnitude, "magnitude", 1, 0, 0, scm_magnitude, g_magnitude);
 
 SCM
 scm_magnitude (z)
@@ -4395,15 +4395,14 @@ scm_magnitude (z)
   SCM_ASRTGO (SCM_NIMP (z), badz);
   if (SCM_BIGP (z))
     return scm_abs (z);
-#ifndef SCM_RECKLESS
   if (!(SCM_INEXP (z)))
     {
     badz:
-      scm_wta (z, (char *) SCM_ARG1, s_magnitude);
+      SCM_WTA_DISPATCH_1 (g_magnitude, z, SCM_ARG1, s_magnitude);
     }
-#endif
 #else
-  SCM_ASSERT (SCM_NIMP (z) && SCM_INEXP (z), z, SCM_ARG1, s_magnitude);
+  SCM_GASSERT1 (SCM_NIMP (z) && SCM_INEXP (z),
+               g_magnitude, z, SCM_ARG1, s_magnitude);
 #endif
   if (SCM_CPLXP (z))
     {
@@ -4416,7 +4415,7 @@ scm_magnitude (z)
 
 
 
-SCM_PROC (s_angle, "angle", 1, 0, 0, scm_angle);
+SCM_GPROC (s_angle, "angle", 1, 0, 0, scm_angle, g_angle);
 
 SCM
 scm_angle (z)
@@ -4435,15 +4434,13 @@ scm_angle (z)
       x = (SCM_TYP16 (z) == scm_tc16_bigpos) ? 1.0 : -1.0;
       goto do_angle;
     }
-#ifndef SCM_RECKLESS
   if (!(SCM_INEXP (z)))
     {
     badz:
-      scm_wta (z, (char *) SCM_ARG1, s_angle);
+      SCM_WTA_DISPATCH_1 (g_angle, z, SCM_ARG1, s_angle);
     }
-#endif
 #else
-  SCM_ASSERT (SCM_NIMP (z) && SCM_INEXP (z), z, SCM_ARG1, s_angle);
+  SCM_GASSERT1 (SCM_NIMP (z) && SCM_INEXP (z), g_angle, z, SCM_ARG1, s_angle);
 #endif
   if (SCM_REALP (z))
     {
@@ -4489,7 +4486,7 @@ scm_inexact_to_exact (z)
        if (SCM_INUM (ans) == (long) u)
          return ans;
       }
-    SCM_ASRTGO (!IS_INF (u), badz);    /* problem? */
+    SCM_ASRTGO (isfinite (u), badz);   /* problem? */
     return scm_dbl2big (u);
   }
 #else
@@ -4500,13 +4497,13 @@ scm_inexact_to_exact (z)
 
 
 #else /* ~SCM_FLOATS */
-SCM_PROC (s_trunc, "truncate", 1, 0, 0, scm_trunc);
+SCM_GPROC (s_trunc, "truncate", 1, 0, 0, scm_trunc, g_trunc);
 
 SCM
 scm_trunc (x)
      SCM x;
 {
-  SCM_ASSERT (SCM_INUMP (x), x, SCM_ARG1, s_truncate);
+  SCM_GASSERT2 (SCM_INUMP (x), g_trunc, x, y, SCM_ARG1, s_truncate);
   return x;
 }
 
@@ -4792,15 +4789,14 @@ add1 (f, fsum)
 void
 scm_init_numbers ()
 {
+  scm_add_feature("complex");
 #ifdef SCM_FLOATS
-  SCM_NEWCELL (scm_flo0);
+  scm_add_feature("inexact");
 #ifdef SCM_SINGLES
-  SCM_SETCAR (scm_flo0, scm_tc_flo);
-  SCM_FLO (scm_flo0) = 0.0;
+  SCM_NEWSMOB(scm_flo0,scm_tc_flo,NULL);
 #else
-  SCM_SETCDR (scm_flo0, (SCM) scm_must_malloc (1L * sizeof (double), "real"));
+  SCM_NEWSMOB(scm_flo0,scm_tc_dblr,scm_must_malloc (1L * sizeof (double), "real"));
   SCM_REAL (scm_flo0) = 0.0;
-  SCM_SETCAR (scm_flo0, scm_tc_dblr);
 #endif
 #ifdef DBL_DIG
   scm_dblprec = (DBL_DIG > 20) ? 20 : DBL_DIG;