зеркало из https://github.com/github/ruby.git
* bignum.c (bigand_int): Consider negative values.
(bigor_int): The allocated bignum should have enough size to store long. This fixes (bignum fits in a BDIGIT) | (fixnum bigger than BDIGIT) on platforms which SIZEOF_BDIGITS < SIZEOF_LONG, such as LP64 with 32bit BDIGIT (no int128). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41639 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
3a81008354
Коммит
9be51267b5
|
@ -1,3 +1,12 @@
|
|||
Wed Jun 26 12:13:12 2013 Tanaka Akira <akr@fsij.org>
|
||||
|
||||
* bignum.c (bigand_int): Consider negative values.
|
||||
(bigor_int): The allocated bignum should have enough size
|
||||
to store long.
|
||||
This fixes (bignum fits in a BDIGIT) | (fixnum bigger than BDIGIT)
|
||||
on platforms which SIZEOF_BDIGITS < SIZEOF_LONG,
|
||||
such as LP64 with 32bit BDIGIT (no int128).
|
||||
|
||||
Wed Jun 26 12:08:51 2013 Tanaka Akira <akr@fsij.org>
|
||||
|
||||
* test/socket/test_udp.rb: Close sockets explicitly.
|
||||
|
|
64
bignum.c
64
bignum.c
|
@ -4643,6 +4643,10 @@ bigand_int(VALUE x, long y)
|
|||
return LONG2NUM(y);
|
||||
}
|
||||
#endif
|
||||
#if SIZEOF_BDIGITS < SIZEOF_LONG
|
||||
if (RBIGNUM_NEGATIVE_P(x) && zn < bdigit_roomof(SIZEOF_LONG))
|
||||
zn = bdigit_roomof(SIZEOF_LONG);
|
||||
#endif
|
||||
|
||||
z = bignew(zn, RBIGNUM_SIGN(x) || sign);
|
||||
zds = BDIGITS(z);
|
||||
|
@ -4656,10 +4660,18 @@ bigand_int(VALUE x, long y)
|
|||
zds[i] = xds[i] & BIGLO(y);
|
||||
y = BIGDN(y);
|
||||
}
|
||||
for (; i < zn; i++) {
|
||||
if (y == 0 || y == -1) break;
|
||||
zds[i] = RBIGNUM_NEGATIVE_P(x) ? BIGLO(y) : 0;
|
||||
y = BIGDN(y);
|
||||
}
|
||||
|
||||
#endif
|
||||
while (i < xn) {
|
||||
for (;i < xn; i++) {
|
||||
zds[i] = sign?0:xds[i];
|
||||
i++;
|
||||
}
|
||||
for (;i < zn; i++) {
|
||||
zds[i] = (!sign && RBIGNUM_NEGATIVE_P(x)) ? BDIGMAX : 0;
|
||||
}
|
||||
if (!RBIGNUM_SIGN(z)) get2comp(z);
|
||||
return bignorm(z);
|
||||
|
@ -4737,26 +4749,54 @@ bigor_int(VALUE x, long y)
|
|||
sign = (y >= 0);
|
||||
xds = BDIGITS(x);
|
||||
zn = xn = RBIGNUM_LEN(x);
|
||||
#if SIZEOF_BDIGITS < SIZEOF_LONG
|
||||
if (zn < bdigit_roomof(SIZEOF_LONG))
|
||||
zn = bdigit_roomof(SIZEOF_LONG);
|
||||
#endif
|
||||
z = bignew(zn, RBIGNUM_SIGN(x) && sign);
|
||||
zds = BDIGITS(z);
|
||||
|
||||
#if SIZEOF_BDIGITS >= SIZEOF_LONG
|
||||
i = 1;
|
||||
zds[0] = xds[0] | y;
|
||||
if (i < zn)
|
||||
goto y_is_fixed_point;
|
||||
goto finish;
|
||||
#else
|
||||
{
|
||||
long num = y;
|
||||
|
||||
for (i=0; i<bdigit_roomof(SIZEOF_LONG); i++) {
|
||||
zds[i] = xds[i] | BIGLO(num);
|
||||
num = BIGDN(num);
|
||||
}
|
||||
for (i=0; i < xn; i++) {
|
||||
if (y == 0 || y == -1) goto y_is_fixed_point;
|
||||
zds[i] = xds[i] | BIGLO(y);
|
||||
y = BIGDN(y);
|
||||
}
|
||||
if (RBIGNUM_NEGATIVE_P(x))
|
||||
goto fill_hibits;
|
||||
for (; i < zn; i++) {
|
||||
if (y == 0 || y == -1) goto y_is_fixed_point;
|
||||
zds[i] = BIGLO(y);
|
||||
y = BIGDN(y);
|
||||
}
|
||||
goto finish;
|
||||
#endif
|
||||
while (i < xn) {
|
||||
zds[i] = sign?xds[i]:BDIGMAX;
|
||||
i++;
|
||||
|
||||
y_is_fixed_point:
|
||||
if (!sign)
|
||||
goto fill_hibits;
|
||||
for (; i < xn; i++) {
|
||||
zds[i] = xds[i];
|
||||
}
|
||||
if (RBIGNUM_NEGATIVE_P(x))
|
||||
goto fill_hibits;
|
||||
for (; i < zn; i++) {
|
||||
zds[i] = 0;
|
||||
}
|
||||
goto finish;
|
||||
|
||||
fill_hibits:
|
||||
for (; i < zn; i++) {
|
||||
zds[i] = BDIGMAX;
|
||||
}
|
||||
|
||||
finish:
|
||||
if (!RBIGNUM_SIGN(z)) get2comp(z);
|
||||
return bignorm(z);
|
||||
}
|
||||
|
|
|
@ -123,6 +123,12 @@ class TestBignum < Test::Unit::TestCase
|
|||
T1024 = b.coerce(2**1024).first
|
||||
T1024P = b.coerce(T1024 - 1).first
|
||||
|
||||
f = b
|
||||
while Bignum === f-1
|
||||
f = f >> 1
|
||||
end
|
||||
FIXNUM_MAX = f-1
|
||||
|
||||
def test_prepare
|
||||
assert_instance_of(Bignum, T_ZERO)
|
||||
assert_instance_of(Bignum, T_ONE)
|
||||
|
@ -454,6 +460,7 @@ class TestBignum < Test::Unit::TestCase
|
|||
assert_equal(T32 + T31, T32 | T31)
|
||||
assert_equal(-T31, (-T32) | (-T31))
|
||||
assert_equal(T64 + T32, T32 | T64)
|
||||
assert_equal(FIXNUM_MAX, T_ZERO | FIXNUM_MAX)
|
||||
end
|
||||
|
||||
def test_xor
|
||||
|
|
|
@ -106,6 +106,8 @@ class TestIntegerComb < Test::Unit::TestCase
|
|||
]
|
||||
|
||||
#VS.map! {|v| 0x4000000000000000.coerce(v)[0] }
|
||||
#VS.concat VS.find_all {|v| Fixnum === v }.map {|v| 0x4000000000000000.coerce(v)[0] }
|
||||
#VS.sort! {|a, b| a.abs <=> b.abs }
|
||||
|
||||
min = -1
|
||||
min *= 2 while min.class == Fixnum
|
||||
|
|
Загрузка…
Ссылка в новой задаче