* bignum.c (get2comp): Use bary_2comp.
(abs2twocomp_bang): New function. (abs2twocomp): New function. (twocomp2abs_bang): New function. (rb_big_and): Use abs2twocomp and twocomp2abs_bang. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41680 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
bc47f294ee
commit
cd6912a595
@ -1,3 +1,11 @@
|
|||||||
|
Thu Jun 27 22:52:19 2013 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
|
* bignum.c (get2comp): Use bary_2comp.
|
||||||
|
(abs2twocomp_bang): New function.
|
||||||
|
(abs2twocomp): New function.
|
||||||
|
(twocomp2abs_bang): New function.
|
||||||
|
(rb_big_and): Use abs2twocomp and twocomp2abs_bang.
|
||||||
|
|
||||||
Thu Jun 27 20:03:13 2013 CHIKANAGA Tomoyuki <nagachika@ruby-lang.org>
|
Thu Jun 27 20:03:13 2013 CHIKANAGA Tomoyuki <nagachika@ruby-lang.org>
|
||||||
|
|
||||||
* ext/openssl/lib/openssl/ssl.rb (verify_certificate_identity): fix
|
* ext/openssl/lib/openssl/ssl.rb (verify_certificate_identity): fix
|
||||||
|
102
bignum.c
102
bignum.c
@ -289,17 +289,8 @@ get2comp(VALUE x)
|
|||||||
{
|
{
|
||||||
long i = RBIGNUM_LEN(x);
|
long i = RBIGNUM_LEN(x);
|
||||||
BDIGIT *ds = BDIGITS(x);
|
BDIGIT *ds = BDIGITS(x);
|
||||||
BDIGIT_DBL num;
|
|
||||||
|
|
||||||
if (!i) return;
|
if (bary_2comp(ds, i)) {
|
||||||
while (i--) ds[i] = BIGLO(~ds[i]);
|
|
||||||
i = 0; num = 1;
|
|
||||||
do {
|
|
||||||
num += ds[i];
|
|
||||||
ds[i++] = BIGLO(num);
|
|
||||||
num = BIGDN(num);
|
|
||||||
} while (i < RBIGNUM_LEN(x));
|
|
||||||
if (num != 0) {
|
|
||||||
rb_big_resize(x, RBIGNUM_LEN(x)+1);
|
rb_big_resize(x, RBIGNUM_LEN(x)+1);
|
||||||
ds = BDIGITS(x);
|
ds = BDIGITS(x);
|
||||||
ds[RBIGNUM_LEN(x)-1] = 1;
|
ds[RBIGNUM_LEN(x)-1] = 1;
|
||||||
@ -312,6 +303,50 @@ rb_big_2comp(VALUE x) /* get 2's complement */
|
|||||||
get2comp(x);
|
get2comp(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BDIGIT
|
||||||
|
abs2twocomp_bang(VALUE x)
|
||||||
|
{
|
||||||
|
long numbdigits = RBIGNUM_LEN(x);
|
||||||
|
long n;
|
||||||
|
BDIGIT *ds = BDIGITS(x);
|
||||||
|
BDIGIT hibits;
|
||||||
|
|
||||||
|
n = numbdigits;
|
||||||
|
|
||||||
|
while (0 < n && ds[n-1] == 0)
|
||||||
|
n--;
|
||||||
|
|
||||||
|
if (n == 0 || RBIGNUM_POSITIVE_P(x))
|
||||||
|
hibits = 0;
|
||||||
|
else {
|
||||||
|
hibits = BDIGMAX;
|
||||||
|
bary_2comp(ds, numbdigits);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hibits;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BDIGIT
|
||||||
|
abs2twocomp(VALUE *xp)
|
||||||
|
{
|
||||||
|
VALUE x = *xp;
|
||||||
|
BDIGIT hibits = 0;
|
||||||
|
if (RBIGNUM_NEGATIVE_P(x)) {
|
||||||
|
*xp = x = rb_big_clone(x);
|
||||||
|
hibits = abs2twocomp_bang(x);
|
||||||
|
}
|
||||||
|
return hibits;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
twocomp2abs_bang(VALUE x, int hibits)
|
||||||
|
{
|
||||||
|
RBIGNUM_SET_SIGN(x, !hibits);
|
||||||
|
if (hibits) {
|
||||||
|
get2comp(x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static inline VALUE
|
static inline VALUE
|
||||||
bigtrunc(VALUE x)
|
bigtrunc(VALUE x)
|
||||||
{
|
{
|
||||||
@ -4691,55 +4726,48 @@ bigand_int(VALUE x, long y)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_big_and(VALUE xx, VALUE yy)
|
rb_big_and(VALUE x, VALUE y)
|
||||||
{
|
{
|
||||||
volatile VALUE x, y, z;
|
VALUE z;
|
||||||
BDIGIT *ds1, *ds2, *zds;
|
BDIGIT *ds1, *ds2, *zds;
|
||||||
long i, l1, l2;
|
long i, l1, l2;
|
||||||
char sign;
|
BDIGIT hibitsx, hibitsy;
|
||||||
|
BDIGIT hibits1, hibits2;
|
||||||
|
VALUE tmpv;
|
||||||
|
BDIGIT tmph;
|
||||||
|
|
||||||
if (!FIXNUM_P(yy) && !RB_TYPE_P(yy, T_BIGNUM)) {
|
if (!FIXNUM_P(y) && !RB_TYPE_P(y, T_BIGNUM)) {
|
||||||
return rb_num_coerce_bit(xx, yy, '&');
|
return rb_num_coerce_bit(x, y, '&');
|
||||||
}
|
}
|
||||||
|
|
||||||
x = xx;
|
hibitsx = abs2twocomp(&x);
|
||||||
y = yy;
|
|
||||||
|
|
||||||
if (!RBIGNUM_SIGN(x)) {
|
|
||||||
x = rb_big_clone(x);
|
|
||||||
get2comp(x);
|
|
||||||
}
|
|
||||||
if (FIXNUM_P(y)) {
|
if (FIXNUM_P(y)) {
|
||||||
return bigand_int(x, FIX2LONG(y));
|
return bigand_int(x, FIX2LONG(y));
|
||||||
}
|
}
|
||||||
if (!RBIGNUM_SIGN(y)) {
|
hibitsy = abs2twocomp(&y);
|
||||||
y = rb_big_clone(y);
|
|
||||||
get2comp(y);
|
|
||||||
}
|
|
||||||
if (RBIGNUM_LEN(x) > RBIGNUM_LEN(y)) {
|
if (RBIGNUM_LEN(x) > RBIGNUM_LEN(y)) {
|
||||||
l1 = RBIGNUM_LEN(y);
|
tmpv = x; x = y; y = tmpv;
|
||||||
l2 = RBIGNUM_LEN(x);
|
tmph = hibitsx; hibitsx = hibitsy; hibitsy = tmph;
|
||||||
ds1 = BDIGITS(y);
|
|
||||||
ds2 = BDIGITS(x);
|
|
||||||
sign = RBIGNUM_SIGN(y);
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
l1 = RBIGNUM_LEN(x);
|
l1 = RBIGNUM_LEN(x);
|
||||||
l2 = RBIGNUM_LEN(y);
|
l2 = RBIGNUM_LEN(y);
|
||||||
ds1 = BDIGITS(x);
|
ds1 = BDIGITS(x);
|
||||||
ds2 = BDIGITS(y);
|
ds2 = BDIGITS(y);
|
||||||
sign = RBIGNUM_SIGN(x);
|
hibits1 = hibitsx;
|
||||||
}
|
hibits2 = hibitsy;
|
||||||
z = bignew(l2, RBIGNUM_SIGN(x) || RBIGNUM_SIGN(y));
|
|
||||||
|
z = bignew(l2, 0);
|
||||||
zds = BDIGITS(z);
|
zds = BDIGITS(z);
|
||||||
|
|
||||||
for (i=0; i<l1; i++) {
|
for (i=0; i<l1; i++) {
|
||||||
zds[i] = ds1[i] & ds2[i];
|
zds[i] = ds1[i] & ds2[i];
|
||||||
}
|
}
|
||||||
for (; i<l2; i++) {
|
for (; i<l2; i++) {
|
||||||
zds[i] = sign?0:ds2[i];
|
zds[i] = hibits1 & ds2[i];
|
||||||
}
|
}
|
||||||
if (!RBIGNUM_SIGN(z)) get2comp(z);
|
twocomp2abs_bang(z, hibits1 && hibits2);
|
||||||
|
RB_GC_GUARD(x);
|
||||||
|
RB_GC_GUARD(y);
|
||||||
return bignorm(z);
|
return bignorm(z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user