+ else if (SCM_BIGP (x))
+ {
+ if (SCM_INUMP (y))
+ {
+ SCM_SWAP (x, y);
+ goto intbig;
+ }
+ else if (SCM_BIGP (y))
+ {
+ SCM result = scm_i_mkbig ();
+ mpz_mul (SCM_I_BIG_MPZ (result),
+ SCM_I_BIG_MPZ (x),
+ SCM_I_BIG_MPZ (y));
+ scm_remember_upto_here_2 (x, y);
+ return result;
+ }
+ else if (SCM_REALP (y))
+ {
+ double result = mpz_get_d (SCM_I_BIG_MPZ (x)) * SCM_REAL_VALUE (y);
+ scm_remember_upto_here_1 (x);
+ return scm_make_real (result);
+ }
+ else if (SCM_COMPLEXP (y))
+ {
+ double z = mpz_get_d (SCM_I_BIG_MPZ (x));
+ scm_remember_upto_here_1 (x);
+ return scm_make_complex (z * SCM_COMPLEX_REAL (y),
+ z * SCM_COMPLEX_IMAG (y));
+ }
+ else if (SCM_FRACTIONP (y))
+ return scm_make_ratio (scm_product (x, SCM_FRACTION_NUMERATOR (y)),
+ SCM_FRACTION_DENOMINATOR (y));
+ else
+ SCM_WTA_DISPATCH_2 (g_product, x, y, SCM_ARGn, s_product);
+ }
+ else if (SCM_REALP (x))
+ {
+ if (SCM_INUMP (y))
+ return scm_make_real (SCM_INUM (y) * SCM_REAL_VALUE (x));
+ else if (SCM_BIGP (y))
+ {
+ double result = mpz_get_d (SCM_I_BIG_MPZ (y)) * SCM_REAL_VALUE (x);
+ scm_remember_upto_here_1 (y);
+ return scm_make_real (result);
+ }
+ else if (SCM_REALP (y))
+ return scm_make_real (SCM_REAL_VALUE (x) * SCM_REAL_VALUE (y));
+ else if (SCM_COMPLEXP (y))
+ return scm_make_complex (SCM_REAL_VALUE (x) * SCM_COMPLEX_REAL (y),
+ SCM_REAL_VALUE (x) * SCM_COMPLEX_IMAG (y));
+ else if (SCM_FRACTIONP (y))
+ return scm_make_real (SCM_REAL_VALUE (x) * scm_i_fraction2double (y));
+ else
+ SCM_WTA_DISPATCH_2 (g_product, x, y, SCM_ARGn, s_product);
+ }
+ else if (SCM_COMPLEXP (x))
+ {
+ if (SCM_INUMP (y))
+ return scm_make_complex (SCM_INUM (y) * SCM_COMPLEX_REAL (x),
+ SCM_INUM (y) * SCM_COMPLEX_IMAG (x));
+ else if (SCM_BIGP (y))
+ {
+ double z = mpz_get_d (SCM_I_BIG_MPZ (y));
+ scm_remember_upto_here_1 (y);
+ return scm_make_complex (z * SCM_COMPLEX_REAL (x),
+ z * SCM_COMPLEX_IMAG (x));
+ }
+ else if (SCM_REALP (y))
+ return scm_make_complex (SCM_REAL_VALUE (y) * SCM_COMPLEX_REAL (x),
+ SCM_REAL_VALUE (y) * SCM_COMPLEX_IMAG (x));
+ else if (SCM_COMPLEXP (y))
+ {
+ return scm_make_complex (SCM_COMPLEX_REAL (x) * SCM_COMPLEX_REAL (y)
+ - SCM_COMPLEX_IMAG (x) * SCM_COMPLEX_IMAG (y),
+ SCM_COMPLEX_REAL (x) * SCM_COMPLEX_IMAG (y)
+ + SCM_COMPLEX_IMAG (x) * SCM_COMPLEX_REAL (y));
+ }
+ else if (SCM_FRACTIONP (y))
+ {
+ double yy = scm_i_fraction2double (y);
+ return scm_make_complex (yy * SCM_COMPLEX_REAL (x),
+ yy * SCM_COMPLEX_IMAG (x));
+ }
+ else
+ SCM_WTA_DISPATCH_2 (g_product, x, y, SCM_ARGn, s_product);
+ }
+ else if (SCM_FRACTIONP (x))
+ {
+ if (SCM_INUMP (y))
+ return scm_make_ratio (scm_product (y, SCM_FRACTION_NUMERATOR (x)),
+ SCM_FRACTION_DENOMINATOR (x));
+ else if (SCM_BIGP (y))
+ return scm_make_ratio (scm_product (y, SCM_FRACTION_NUMERATOR (x)),
+ SCM_FRACTION_DENOMINATOR (x));
+ else if (SCM_REALP (y))
+ return scm_make_real (scm_i_fraction2double (x) * SCM_REAL_VALUE (y));
+ else if (SCM_COMPLEXP (y))
+ {
+ double xx = scm_i_fraction2double (x);
+ return scm_make_complex (xx * SCM_COMPLEX_REAL (y),
+ xx * SCM_COMPLEX_IMAG (y));
+ }
+ else if (SCM_FRACTIONP (y))
+ /* a/b * c/d = ac / bd */
+ return scm_make_ratio (scm_product (SCM_FRACTION_NUMERATOR (x),
+ SCM_FRACTION_NUMERATOR (y)),
+ scm_product (SCM_FRACTION_DENOMINATOR (x),
+ SCM_FRACTION_DENOMINATOR (y)));
+ else
+ SCM_WTA_DISPATCH_2 (g_product, x, y, SCM_ARGn, s_product);
+ }
+ else