/*
 *  call-seq:
 *     big <=> numeric   => -1, 0, +1
 *
 *  Comparison---Returns -1, 0, or +1 depending on whether <i>big</i> is
 *  less than, equal to, or greater than <i>numeric</i>. This is the
 *  basis for the tests in <code>Comparable</code>.
 *
 */

VALUE
rb_big_cmp(VALUE x, VALUE y)
{
    long xlen = RBIGNUM_LEN(x);

    switch (TYPE(y)) {
      case T_FIXNUM:
        y = rb_int2big(FIX2LONG(y));
        break;

      case T_BIGNUM:
        break;

      case T_FLOAT:
        return rb_dbl_cmp(rb_big2dbl(x), RFLOAT_VALUE(y));

      default:
        return rb_num_coerce_cmp(x, y, rb_intern("<=>"));
    }

    if (RBIGNUM_SIGN(x) > RBIGNUM_SIGN(y)) return INT2FIX(1);
    if (RBIGNUM_SIGN(x) < RBIGNUM_SIGN(y)) return INT2FIX(-1);
    if (xlen < RBIGNUM_LEN(y))
        return (RBIGNUM_SIGN(x)) ? INT2FIX(-1) : INT2FIX(1);
    if (xlen > RBIGNUM_LEN(y))
        return (RBIGNUM_SIGN(x)) ? INT2FIX(1) : INT2FIX(-1);

    while(xlen-- && (BDIGITS(x)[xlen]==BDIGITS(y)[xlen]));
    if (-1 == xlen) return INT2FIX(0);
    return (BDIGITS(x)[xlen] > BDIGITS(y)[xlen]) ?
        (RBIGNUM_SIGN(x) ? INT2FIX(1) : INT2FIX(-1)) :
            (RBIGNUM_SIGN(x) ? INT2FIX(-1) : INT2FIX(1));
}