summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-02-13 09:53:17 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-02-13 09:53:17 +0000
commit75f18961d93b283ad9bb2a7e6a385ab0ebf0076e (patch)
tree8cb2edaf9f7377f6ac6c127e76a013b7644e238f
parentfa9344a1b4ceed3dd658d6c1bad1fbc16359cc55 (diff)
downloadruby-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.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/bignum.c b/bignum.c
index c959950e7..d59969cdd 100644
--- a/bignum.c
+++ b/bignum.c
@@ -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);