/* * 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); }