/*
 *  call-seq:
 *     big[n] -> 0, 1
 *  
 *  Bit Reference---Returns the <em>n</em>th bit in the (assumed) binary
 *  representation of <i>big</i>, where <i>big</i>[0] is the least
 *  significant bit.
 *     
 *     a = 9**15
 *     50.downto(0) do |n|
 *       print a[n]
 *     end
 *     
 *  <em>produces:</em>
 *     
 *     000101110110100000111000011110010100111100010111001
 *     
 */

static VALUE
rb_big_aref(x, y)
    VALUE x, y;
{
    BDIGIT *xds;
    BDIGIT_DBL num;
    unsigned long shift;
    long i, s1, s2;

    if (TYPE(y) == T_BIGNUM) {
        if (!RBIGNUM(y)->sign)
            return INT2FIX(0);
        if (RBIGNUM(bigtrunc(y))->len > SIZEOF_LONG/SIZEOF_BDIGITS) {
          out_of_range:
            return RBIGNUM(x)->sign ? INT2FIX(0) : INT2FIX(1);
        }
        shift = big2ulong(y, "long", Qfalse);
    }
    else {
        i = NUM2LONG(y);
        if (i < 0) return INT2FIX(0);
        shift = (VALUE)i;
    }
    s1 = shift/BITSPERDIG;
    s2 = shift%BITSPERDIG;

    if (s1 >= RBIGNUM(x)->len) goto out_of_range;
    if (!RBIGNUM(x)->sign) {
        xds = BDIGITS(x);
        i = 0; num = 1;
        while (num += ~xds[i], ++i <= s1) {
            num = BIGDN(num);
        }
    }
    else {
        num = BDIGITS(x)[s1];
    }
    if (num & ((BDIGIT_DBL)1<<s2))
        return INT2FIX(1);
    return INT2FIX(0);
}