diff options
author | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-06-22 14:28:50 +0000 |
---|---|---|
committer | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-06-22 14:28:50 +0000 |
commit | 963d67895342328c6c2d87fbaaffaebc190e0213 (patch) | |
tree | c0b7e111f31ef471a35bb3f290618b1f6de2ff0a | |
parent | edc338875eaa5590b13aadb818a24e247249d616 (diff) | |
download | ruby-963d67895342328c6c2d87fbaaffaebc190e0213.tar.gz |
* 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
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | bignum.c | 154 |
2 files changed, 32 insertions, 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> * bignum.c (rb_integer_unpack): Don't allocate a Bignum if possible. @@ -250,6 +250,20 @@ rb_big_clone(VALUE x) } 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 bary_2comp(BDIGIT *ds, size_t n) { size_t i = n; @@ -1013,20 +1027,10 @@ bary_pack(int sign, BDIGIT *ds, size_t num_bdigits, void *words, size_t numwords overflow = 1; } if (sign < 0 && (flags & INTEGER_PACK_2COMP)) { - unsigned char *p = words, *e = (unsigned char *)words + dst_size; - while (p < e && *p == 0) - p++; - if (p < e) { - *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; + int zero_p = bytes_2comp(words, dst_size); + if (zero_p && overflow) { + unsigned char *p = (unsigned char *)dp + dst_size; + unsigned char *e = (unsigned char *)dp + src_size; if (p < e && *p++ == 1) { while (p < e && *p == 0) p++; @@ -1854,130 +1858,22 @@ rb_integer_unpack(const void *words, size_t numwords, size_t wordsize, size_t na #define QUAD_SIZE 8 -#if SIZEOF_LONG_LONG == QUAD_SIZE && SIZEOF_BDIGITS*2 == SIZEOF_LONG_LONG - -void -rb_quad_pack(char *buf, VALUE val) -{ - LONG_LONG q; - - val = rb_to_int(val); - 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 -rb_quad_unpack(const char *buf, int sign) -{ - unsigned LONG_LONG q; - long neg = 0; - long i; - 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); - } + rb_integer_pack(val, buf, 1, QUAD_SIZE, 0, + INTEGER_PACK_NATIVE_BYTE_ORDER| + INTEGER_PACK_2COMP); } -#define BNEG(b) (RSHIFT(((BDIGIT*)(b))[QUAD_SIZE/SIZEOF_BDIGITS-1],BITSPERDIG-1) != 0) - VALUE -rb_quad_unpack(const char *buf, int sign) +rb_quad_unpack(const char *buf, int signed_p) { - 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); + return rb_integer_unpack(buf, 1, QUAD_SIZE, 0, + INTEGER_PACK_NATIVE_BYTE_ORDER| + (signed_p ? INTEGER_PACK_2COMP : 0)); } -#endif - VALUE rb_cstr_to_inum(const char *str, int base, int badcheck) { |