mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* bignum.c (bytes_2comp): Renamed from quad_buf_complement.
(bary_pack): Use bytes_2comp. (rb_quad_pack): Use rb_integer_pack. (rb_quad_unpack): Use rb_integer_unpack. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41570 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
edc338875e
commit
963d678953
2 changed files with 32 additions and 129 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
Sat Jun 22 23:18:39 2013 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
|
* bignum.c (bytes_2comp): Renamed from quad_buf_complement.
|
||||||
|
(bary_pack): Use bytes_2comp.
|
||||||
|
(rb_quad_pack): Use rb_integer_pack.
|
||||||
|
(rb_quad_unpack): Use rb_integer_unpack.
|
||||||
|
|
||||||
Sat Jun 22 21:46:18 2013 Tanaka Akira <akr@fsij.org>
|
Sat Jun 22 21:46:18 2013 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
* bignum.c (rb_integer_unpack): Don't allocate a Bignum if possible.
|
* bignum.c (rb_integer_unpack): Don't allocate a Bignum if possible.
|
||||||
|
|
154
bignum.c
154
bignum.c
|
@ -249,6 +249,20 @@ rb_big_clone(VALUE x)
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
bytes_2comp(unsigned char *buf, size_t len)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
buf[i] = ~buf[i];
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
buf[i]++;
|
||||||
|
if (buf[i] != 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bary_2comp(BDIGIT *ds, size_t n)
|
bary_2comp(BDIGIT *ds, size_t n)
|
||||||
{
|
{
|
||||||
|
@ -1013,20 +1027,10 @@ bary_pack(int sign, BDIGIT *ds, size_t num_bdigits, void *words, size_t numwords
|
||||||
overflow = 1;
|
overflow = 1;
|
||||||
}
|
}
|
||||||
if (sign < 0 && (flags & INTEGER_PACK_2COMP)) {
|
if (sign < 0 && (flags & INTEGER_PACK_2COMP)) {
|
||||||
unsigned char *p = words, *e = (unsigned char *)words + dst_size;
|
int zero_p = bytes_2comp(words, dst_size);
|
||||||
while (p < e && *p == 0)
|
if (zero_p && overflow) {
|
||||||
p++;
|
unsigned char *p = (unsigned char *)dp + dst_size;
|
||||||
if (p < e) {
|
unsigned char *e = (unsigned char *)dp + src_size;
|
||||||
*p = 1 + (unsigned char)~*p;
|
|
||||||
p++;
|
|
||||||
while (p < e) {
|
|
||||||
*p = (unsigned char)~*p;
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (overflow) {
|
|
||||||
p = (unsigned char *)dp + dst_size;
|
|
||||||
e = (unsigned char *)dp + src_size;
|
|
||||||
if (p < e && *p++ == 1) {
|
if (p < e && *p++ == 1) {
|
||||||
while (p < e && *p == 0)
|
while (p < e && *p == 0)
|
||||||
p++;
|
p++;
|
||||||
|
@ -1854,130 +1858,22 @@ rb_integer_unpack(const void *words, size_t numwords, size_t wordsize, size_t na
|
||||||
|
|
||||||
#define QUAD_SIZE 8
|
#define QUAD_SIZE 8
|
||||||
|
|
||||||
#if SIZEOF_LONG_LONG == QUAD_SIZE && SIZEOF_BDIGITS*2 == SIZEOF_LONG_LONG
|
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_quad_pack(char *buf, VALUE val)
|
rb_quad_pack(char *buf, VALUE val)
|
||||||
{
|
{
|
||||||
LONG_LONG q;
|
rb_integer_pack(val, buf, 1, QUAD_SIZE, 0,
|
||||||
|
INTEGER_PACK_NATIVE_BYTE_ORDER|
|
||||||
val = rb_to_int(val);
|
INTEGER_PACK_2COMP);
|
||||||
if (FIXNUM_P(val)) {
|
|
||||||
q = FIX2LONG(val);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
long len = RBIGNUM_LEN(val);
|
|
||||||
BDIGIT *ds;
|
|
||||||
|
|
||||||
if (len > SIZEOF_LONG_LONG/SIZEOF_BDIGITS) {
|
|
||||||
len = SIZEOF_LONG_LONG/SIZEOF_BDIGITS;
|
|
||||||
}
|
|
||||||
ds = BDIGITS(val);
|
|
||||||
q = 0;
|
|
||||||
while (len--) {
|
|
||||||
q = BIGUP(q);
|
|
||||||
q += ds[len];
|
|
||||||
}
|
|
||||||
if (!RBIGNUM_SIGN(val)) q = -q;
|
|
||||||
}
|
|
||||||
memcpy(buf, (char*)&q, SIZEOF_LONG_LONG);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_quad_unpack(const char *buf, int sign)
|
rb_quad_unpack(const char *buf, int signed_p)
|
||||||
{
|
{
|
||||||
unsigned LONG_LONG q;
|
return rb_integer_unpack(buf, 1, QUAD_SIZE, 0,
|
||||||
long neg = 0;
|
INTEGER_PACK_NATIVE_BYTE_ORDER|
|
||||||
long i;
|
(signed_p ? INTEGER_PACK_2COMP : 0));
|
||||||
BDIGIT *digits;
|
|
||||||
VALUE big;
|
|
||||||
|
|
||||||
memcpy(&q, buf, SIZEOF_LONG_LONG);
|
|
||||||
if (sign) {
|
|
||||||
if (FIXABLE((LONG_LONG)q)) return LONG2FIX((LONG_LONG)q);
|
|
||||||
if ((LONG_LONG)q < 0) {
|
|
||||||
q = -(LONG_LONG)q;
|
|
||||||
neg = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (POSFIXABLE(q)) return LONG2FIX(q);
|
|
||||||
}
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
big = bignew(DIGSPERLL, 1);
|
|
||||||
digits = BDIGITS(big);
|
|
||||||
while (i < DIGSPERLL) {
|
|
||||||
digits[i++] = BIGLO(q);
|
|
||||||
q = BIGDN(q);
|
|
||||||
}
|
|
||||||
|
|
||||||
i = DIGSPERLL;
|
|
||||||
while (i-- && !digits[i]) ;
|
|
||||||
RBIGNUM_SET_LEN(big, i+1);
|
|
||||||
|
|
||||||
if (neg) {
|
|
||||||
RBIGNUM_SET_SIGN(big, 0);
|
|
||||||
}
|
|
||||||
return bignorm(big);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static int
|
|
||||||
quad_buf_complement(char *buf, size_t len)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
for (i = 0; i < len; i++)
|
|
||||||
buf[i] = ~buf[i];
|
|
||||||
for (i = 0; i < len; i++) {
|
|
||||||
buf[i]++;
|
|
||||||
if (buf[i] != 0)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
rb_quad_pack(char *buf, VALUE val)
|
|
||||||
{
|
|
||||||
long len;
|
|
||||||
|
|
||||||
memset(buf, 0, QUAD_SIZE);
|
|
||||||
val = rb_to_int(val);
|
|
||||||
if (FIXNUM_P(val)) {
|
|
||||||
val = rb_int2big(FIX2LONG(val));
|
|
||||||
}
|
|
||||||
len = RBIGNUM_LEN(val) * SIZEOF_BDIGITS;
|
|
||||||
if (len > QUAD_SIZE) {
|
|
||||||
len = QUAD_SIZE;
|
|
||||||
}
|
|
||||||
memcpy(buf, (char*)BDIGITS(val), len);
|
|
||||||
if (RBIGNUM_NEGATIVE_P(val)) {
|
|
||||||
quad_buf_complement(buf, QUAD_SIZE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define BNEG(b) (RSHIFT(((BDIGIT*)(b))[QUAD_SIZE/SIZEOF_BDIGITS-1],BITSPERDIG-1) != 0)
|
|
||||||
|
|
||||||
VALUE
|
|
||||||
rb_quad_unpack(const char *buf, int sign)
|
|
||||||
{
|
|
||||||
VALUE big = bignew(QUAD_SIZE/SIZEOF_BDIGITS, 1);
|
|
||||||
|
|
||||||
memcpy((char*)BDIGITS(big), buf, QUAD_SIZE);
|
|
||||||
if (sign && BNEG(buf)) {
|
|
||||||
char *tmp = (char*)BDIGITS(big);
|
|
||||||
|
|
||||||
RBIGNUM_SET_SIGN(big, 0);
|
|
||||||
quad_buf_complement(tmp, QUAD_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return bignorm(big);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_cstr_to_inum(const char *str, int base, int badcheck)
|
rb_cstr_to_inum(const char *str, int base, int badcheck)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue