(scm_make_ratio): For inum/bignum integer detection, use
[bpt/guile.git] / libguile / numbers.c
index 6023f70..9c98076 100644 (file)
@@ -148,7 +148,6 @@ xisnan (double x)
 
 \f
 
-static SCM abs_most_negative_fixnum;
 static mpz_t z_negative_one;
 
 \f
@@ -370,9 +369,12 @@ scm_make_ratio (SCM numerator, SCM denominator)
       else
         {
           /* When x == SCM_MOST_NEGATIVE_FIXNUM we could have the negative
-             of that value for the denominator, as a bignum.  */
-          long  abs_x = (x >= 0 ? x : -x);
-          if (mpz_cmpabs_ui (SCM_I_BIG_MPZ (denominator), abs_x) == 0)
+             of that value for the denominator, as a bignum.  Apart from
+             that case, abs(bignum) > abs(inum) so inum/bignum is not an
+             integer.  */
+          if (x == SCM_MOST_NEGATIVE_FIXNUM
+              && mpz_cmp_ui (SCM_I_BIG_MPZ (denominator),
+                             - SCM_MOST_NEGATIVE_FIXNUM) == 0)
            return SCM_MAKINUM(-1);
         }
     }
@@ -703,9 +705,13 @@ scm_quotient (SCM x, SCM y)
       else if (SCM_BIGP (y))
        {
          if ((SCM_INUM (x) == SCM_MOST_NEGATIVE_FIXNUM)
-             && (scm_i_bigcmp (abs_most_negative_fixnum, y) == 0))
-           /* Special case:  x == fixnum-min && y == abs (fixnum-min) */
-           return SCM_MAKINUM (-1);
+             && (mpz_cmp_ui (SCM_I_BIG_MPZ (y),
+                              - SCM_MOST_NEGATIVE_FIXNUM) == 0))
+            {
+              /* Special case:  x == fixnum-min && y == abs (fixnum-min) */
+             scm_remember_upto_here_1 (y);
+              return SCM_MAKINUM (-1);
+            }
          else
            return SCM_MAKINUM (0);
        }
@@ -779,9 +785,13 @@ scm_remainder (SCM x, SCM y)
       else if (SCM_BIGP (y))
        {
          if ((SCM_INUM (x) == SCM_MOST_NEGATIVE_FIXNUM)
-             && (scm_i_bigcmp (abs_most_negative_fixnum, y) == 0))
-           /* Special case:  x == fixnum-min && y == abs (fixnum-min) */
-           return SCM_MAKINUM (0);
+             && (mpz_cmp_ui (SCM_I_BIG_MPZ (y),
+                              - SCM_MOST_NEGATIVE_FIXNUM) == 0))
+            {
+              /* Special case:  x == fixnum-min && y == abs (fixnum-min) */
+             scm_remember_upto_here_1 (y);
+              return SCM_MAKINUM (0);
+            }
          else
            return x;
        }
@@ -5690,9 +5700,6 @@ SCM_DEFINE (scm_sys_check_number_conversions, "%check-number-conversions", 0, 0,
 void
 scm_init_numbers ()
 {
-  abs_most_negative_fixnum = scm_i_long2big (- SCM_MOST_NEGATIVE_FIXNUM);
-  scm_permanent_object (abs_most_negative_fixnum);
-
   mpz_init_set_si (z_negative_one, -1);
 
   /* It may be possible to tune the performance of some algorithms by using