diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2002-02-13 09:53:17 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2002-02-13 09:53:17 +0000 |
commit | 75f18961d93b283ad9bb2a7e6a385ab0ebf0076e (patch) | |
tree | 8cb2edaf9f7377f6ac6c127e76a013b7644e238f | |
parent | fa9344a1b4ceed3dd658d6c1bad1fbc16359cc55 (diff) | |
download | ruby-75f18961d93b283ad9bb2a7e6a385ab0ebf0076e.tar.gz ruby-75f18961d93b283ad9bb2a7e6a385ab0ebf0076e.tar.xz ruby-75f18961d93b283ad9bb2a7e6a385ab0ebf0076e.zip |
* bignum.c: forget to check in DIGSPERLONGLONG.
git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@2066 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | bignum.c | 20 |
1 files changed, 18 insertions, 2 deletions
@@ -187,6 +187,8 @@ rb_int2inum(n) #ifdef HAVE_LONG_LONG +#define DIGSPERLONGLONG ((unsigned int)(sizeof(LONG_LONG)/sizeof(BDIGIT))) + void rb_quad_pack(buf, val) char *buf; @@ -267,13 +269,21 @@ rb_quad_pack(buf, val) memset(buf, 0, QUAD_SIZE); val = rb_to_int(val); if (FIXNUM_P(val)) { - val = rb_uint2big(FIX2LONG(val)); + val = rb_int2big(FIX2LONG(val)); } len = RBIGNUM(val)->len * sizeof(BDIGIT); if (len > QUAD_SIZE) len = QUAD_SIZE; memcpy(buf, (char*)BDIGITS(val), len); + if (!RBIGNUM(val)->sign) { + len = QUAD_SIZE; + while (len--) { + *buf = ~*buf++; + } + } } +#define BNEG(b) (RSHIFT(((BDIGIT*)b)[QUAD_SIZE/sizeof(BDIGIT)-1],BITSPERDIG-1) != 0) + VALUE rb_quad_unpack(buf, sign) const char *buf; @@ -282,8 +292,14 @@ rb_quad_unpack(buf, sign) VALUE big = bignew(QUAD_SIZE/sizeof(BDIGIT), 1); memcpy((char*)BDIGITS(big), buf, QUAD_SIZE); - if (sign && (buf[7] & 0x80)) { + if (sign && BNEG(buf)) { + long len = QUAD_SIZE; + char *tmp = (char*)BDIGITS(big); + RBIGNUM(big)->sign = 0; + while (len--) { + *tmp = ~*tmp++; + } } return bignorm(big); |