^(p1)
public
Performs bitwise +exclusive or+ between big and numeric.
Show source
VALUE
rb_big_xor(VALUE x, VALUE y)
{
VALUE z;
BDIGIT *ds1, *ds2, *zds;
long i, xn, yn, n1, n2;
BDIGIT hibitsx, hibitsy;
BDIGIT hibits1, hibits2;
VALUE tmpv;
BDIGIT tmph;
long tmpn;
if (!FIXNUM_P(y) && !RB_BIGNUM_TYPE_P(y)) {
return rb_num_coerce_bit(x, y, '^');
}
hibitsx = abs2twocomp(&x, &xn);
if (FIXNUM_P(y)) {
return bigxor_int(x, xn, hibitsx, FIX2LONG(y));
}
hibitsy = abs2twocomp(&y, &yn);
if (xn > yn) {
tmpv = x; x = y; y = tmpv;
tmpn = xn; xn = yn; yn = tmpn;
tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
}
n1 = xn;
n2 = yn;
ds1 = BDIGITS(x);
ds2 = BDIGITS(y);
hibits1 = hibitsx;
hibits2 = hibitsy;
z = bignew(n2, 0);
zds = BDIGITS(z);
for (i=0; i<n1; i++) {
zds[i] = ds1[i] ^ ds2[i];
}
for (; i<n2; i++) {
zds[i] = hibitsx ^ ds2[i];
}
twocomp2abs_bang(z, (hibits1 ^ hibits2) != 0);
RB_GC_GUARD(x);
RB_GC_GUARD(y);
return bignorm(z);
}