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)) |
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)) |
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 |
{ |
{ |