/[guile]/guile/guile-core/libguile/numbers.c
ViewVC logotype

Diff of /guile/guile-core/libguile/numbers.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.211 by mvo, Wed Nov 19 04:30:40 2003 UTC revision 1.212 by mvo, Wed Nov 19 05:12:08 2003 UTC
# Line 325  static SCM scm_divide2real (SCM x, SCM y Line 325  static SCM scm_divide2real (SCM x, SCM y
325    
326  SCM  SCM
327  scm_make_ratio (SCM numerator, SCM denominator)  scm_make_ratio (SCM numerator, SCM denominator)
328    #define FUNC_NAME "make-ratio"
329  {  {
330  #if 0    /* First make sure the arguments are proper.
331    return scm_divide2real(numerator, denominator);     */
 #else  
   #define FUNC_NAME "make-ratio"  
332    if (SCM_INUMP (denominator))    if (SCM_INUMP (denominator))
333      {      {
334        if (SCM_EQ_P (denominator, SCM_INUM0))        if (SCM_EQ_P (denominator, SCM_INUM0))
# Line 342  scm_make_ratio (SCM numerator, SCM denom Line 341  scm_make_ratio (SCM numerator, SCM denom
341        if (!(SCM_BIGP(denominator)))        if (!(SCM_BIGP(denominator)))
342          SCM_WRONG_TYPE_ARG (2, denominator);          SCM_WRONG_TYPE_ARG (2, denominator);
343      }      }
344      if (!SCM_INUMP (numerator) && !SCM_BIGP (numerator))
345        SCM_WRONG_TYPE_ARG (1, numerator);
346    
347      /* Then flip signs so that the denominator is positive.
348       */
349      if (SCM_NFALSEP (scm_negative_p (denominator)))
350        {
351          numerator = scm_difference (numerator, SCM_UNDEFINED);
352          denominator = scm_difference (denominator, SCM_UNDEFINED);
353        }
354    
355      /* Now consider for each of the four fixnum/bignum combinations
356         whether the rational number is really an integer.
357      */
358    if (SCM_INUMP (numerator))    if (SCM_INUMP (numerator))
359      {      {
360        if (SCM_EQ_P (numerator, SCM_INUM0))        if (SCM_EQ_P (numerator, SCM_INUM0))
# Line 355  scm_make_ratio (SCM numerator, SCM denom Line 368  scm_make_ratio (SCM numerator, SCM denom
368              return SCM_MAKINUM(1);              return SCM_MAKINUM(1);
369            if ((x % y) == 0)            if ((x % y) == 0)
370              return SCM_MAKINUM (x / y);              return SCM_MAKINUM (x / y);
           if (y < 0)  
             return scm_double_cell (scm_tc16_fraction, (scm_t_bits)SCM_MAKINUM(-x), (scm_t_bits)SCM_MAKINUM(-y), 0);  
           else return scm_double_cell (scm_tc16_fraction, (scm_t_bits)numerator, (scm_t_bits)denominator, 0);  
         }  
       else  
         {  
           /* I assume bignums are actually big, so here there's no point in looking for a integer */  
           int sgn = mpz_sgn (SCM_I_BIG_MPZ (denominator));  
           if (sgn < 0) /* if denominator negative, flip signs */  
             return scm_double_cell (scm_tc16_fraction,  
                                     (scm_t_bits)scm_difference (numerator, SCM_UNDEFINED),  
                                     (scm_t_bits)scm_difference (denominator, SCM_UNDEFINED),  
                                     0);  
           else return scm_double_cell (scm_tc16_fraction, (scm_t_bits)numerator, (scm_t_bits)denominator, 0);  
   
           /* should this use SCM_UNPACK for the bignums? */  
371          }          }
372      }      }
373    else    else if (SCM_BIGP (numerator))
374      {      {
375        if (SCM_BIGP (numerator))        if (SCM_INUMP (denominator))
376          {          {
377            /* can't use scm_divide to find integer here */            long yy = SCM_INUM (denominator);
378            if (SCM_INUMP (denominator))            if (mpz_divisible_ui_p (SCM_I_BIG_MPZ (numerator), yy))
379              {              return scm_divide (numerator, denominator);
380                long yy = SCM_INUM (denominator);          }
381                long abs_yy = yy < 0 ? -yy : yy;        else
382                int divisible_p = mpz_divisible_ui_p (SCM_I_BIG_MPZ (numerator), abs_yy);          {
383                if (divisible_p)            if (SCM_EQ_P (numerator, denominator))
384                  return scm_divide(numerator, denominator);              return SCM_MAKINUM(1);
385                else return scm_double_cell (scm_tc16_fraction, (scm_t_bits)numerator, (scm_t_bits)denominator, 0);            if (mpz_divisible_p (SCM_I_BIG_MPZ (numerator),
386              }                                 SCM_I_BIG_MPZ (denominator)))
387            else              return scm_divide(numerator, denominator);
             {  
               /* both are bignums */  
               if (SCM_EQ_P (numerator, denominator))  
                 return SCM_MAKINUM(1);  
               if (mpz_divisible_p (SCM_I_BIG_MPZ (numerator),  
                                    SCM_I_BIG_MPZ (denominator)))  
                 return scm_divide(numerator, denominator);  
               else  
                 return scm_double_cell (scm_tc16_fraction,  
                                         (scm_t_bits)numerator,  
                                         (scm_t_bits)denominator, 0);  
             }  
388          }          }
       else SCM_WRONG_TYPE_ARG (1, numerator);  
389      }      }
390    return SCM_BOOL_F; /* won't happen */  
391    #undef FUNC_NAME    /* No, it's a proper fraction.
392  #endif     */
393      return scm_double_cell (scm_tc16_fraction,
394                              SCM_UNPACK (numerator),
395                              SCM_UNPACK (denominator), 0);
396  }  }
397    #undef FUNC_NAME
398    
399  static void scm_i_fraction_reduce (SCM z)  static void scm_i_fraction_reduce (SCM z)
400  {  {

Legend:
Removed from v.1.211  
changed lines
  Added in v.1.212

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26