mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* bignum.c (bary_2comp): Extracted from get2comp.
(integer_unpack_num_bdigits): Extracted from rb_integer_unpack_internal. (bary_unpack_internal): Renamed from bary_unpack and support INTEGER_PACK_2COMP. (bary_unpack): New function to validate arguments and invoke bary_unpack_internal. (rb_integer_unpack_internal): Removed. (rb_integer_unpack): Invoke bary_unpack_internal. (rb_integer_unpack_2comp): Removed. * internal.h (rb_integer_unpack_2comp): Removed. * pack.c: Follow the above change. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41337 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
ecabbf1bf6
commit
50794b3222
6 changed files with 202 additions and 174 deletions
17
ChangeLog
17
ChangeLog
|
@ -1,3 +1,20 @@
|
|||
Sun Jun 16 21:41:39 2013 Tanaka Akira <akr@fsij.org>
|
||||
|
||||
* bignum.c (bary_2comp): Extracted from get2comp.
|
||||
(integer_unpack_num_bdigits): Extracted from
|
||||
rb_integer_unpack_internal.
|
||||
(bary_unpack_internal): Renamed from bary_unpack and support
|
||||
INTEGER_PACK_2COMP.
|
||||
(bary_unpack): New function to validate arguments and invoke
|
||||
bary_unpack_internal.
|
||||
(rb_integer_unpack_internal): Removed.
|
||||
(rb_integer_unpack): Invoke bary_unpack_internal.
|
||||
(rb_integer_unpack_2comp): Removed.
|
||||
|
||||
* internal.h (rb_integer_unpack_2comp): Removed.
|
||||
|
||||
* pack.c: Follow the above change.
|
||||
|
||||
Sun Jun 16 18:41:42 2013 Tanaka Akira <akr@fsij.org>
|
||||
|
||||
* internal.h (INTEGER_PACK_2COMP): Defined.
|
||||
|
|
298
bignum.c
298
bignum.c
|
@ -64,6 +64,7 @@ static void bary_sub(BDIGIT *zds, size_t zn, BDIGIT *xds, size_t xn, BDIGIT *yds
|
|||
static void bary_divmod(BDIGIT *qds, size_t nq, BDIGIT *rds, size_t nr, BDIGIT *xds, size_t nx, BDIGIT *yds, size_t ny);
|
||||
static void bary_add(BDIGIT *zds, size_t zn, BDIGIT *xds, size_t xn, BDIGIT *yds, size_t yn);
|
||||
static int bary_pack(int sign, BDIGIT *ds, size_t num_bdigits, void *words, size_t numwords, size_t wordsize, size_t nails, int flags);
|
||||
static BDIGIT bary_2comp(BDIGIT *ds, size_t n);
|
||||
|
||||
#define BIGNUM_DEBUG 0
|
||||
#if BIGNUM_DEBUG
|
||||
|
@ -218,6 +219,22 @@ rb_big_clone(VALUE x)
|
|||
return z;
|
||||
}
|
||||
|
||||
static BDIGIT
|
||||
bary_2comp(BDIGIT *ds, size_t n)
|
||||
{
|
||||
size_t i = n;
|
||||
BDIGIT_DBL num;
|
||||
if (!n) return 1;
|
||||
while (i--) ds[i] = ~ds[i];
|
||||
i = 0; num = 1;
|
||||
do {
|
||||
num += ds[i];
|
||||
ds[i++] = BIGLO(num);
|
||||
num = BIGDN(num);
|
||||
} while (i < n);
|
||||
return (BDIGIT)num;
|
||||
}
|
||||
|
||||
/* modify a bignum by 2's complement */
|
||||
static void
|
||||
get2comp(VALUE x)
|
||||
|
@ -1228,6 +1245,28 @@ integer_unpack_num_bdigits_generic(size_t numwords, size_t wordsize, size_t nail
|
|||
}
|
||||
}
|
||||
|
||||
static size_t
|
||||
integer_unpack_num_bdigits(size_t numwords, size_t wordsize, size_t nails, int *nlp_bits_ret)
|
||||
{
|
||||
size_t num_bdigits;
|
||||
|
||||
if (numwords <= (SIZE_MAX - (BITSPERDIG-1)) / CHAR_BIT / wordsize) {
|
||||
num_bdigits = integer_unpack_num_bdigits_small(numwords, wordsize, nails, nlp_bits_ret);
|
||||
#ifdef DEBUG_INTEGER_PACK
|
||||
{
|
||||
int nlp_bits1;
|
||||
size_t num_bdigits1 = integer_unpack_num_bdigits_generic(numwords, wordsize, nails, &nlp_bits1);
|
||||
assert(num_bdigits == num_bdigits1);
|
||||
assert(*nlp_bits_ret == nlp_bits1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
num_bdigits = integer_unpack_num_bdigits_generic(numwords, wordsize, nails, nlp_bits_ret);
|
||||
}
|
||||
return num_bdigits;
|
||||
}
|
||||
|
||||
static inline void
|
||||
integer_unpack_push_bits(int data, int numbits, BDIGIT_DBL *ddp, int *numbits_in_dd_p, BDIGIT **dpp)
|
||||
{
|
||||
|
@ -1240,9 +1279,11 @@ integer_unpack_push_bits(int data, int numbits, BDIGIT_DBL *ddp, int *numbits_in
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
bary_unpack(BDIGIT *bdigits, size_t num_bdigits, const void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
|
||||
static int
|
||||
bary_unpack_internal(BDIGIT *bdigits, size_t num_bdigits, const void *words, size_t numwords, size_t wordsize, size_t nails, int flags, int nlp_bits)
|
||||
{
|
||||
int sign = (flags & INTEGER_PACK_NEGATIVE) ? -1 : 1;
|
||||
|
||||
const unsigned char *buf = words;
|
||||
|
||||
BDIGIT *dp;
|
||||
|
@ -1260,80 +1301,91 @@ bary_unpack(BDIGIT *bdigits, size_t num_bdigits, const void *words, size_t numwo
|
|||
BDIGIT_DBL dd;
|
||||
int numbits_in_dd;
|
||||
|
||||
dp = bdigits;
|
||||
de = dp + num_bdigits;
|
||||
if (num_bdigits) {
|
||||
dp = bdigits;
|
||||
de = dp + num_bdigits;
|
||||
|
||||
integer_pack_loop_setup(numwords, wordsize, nails, flags,
|
||||
&word_num_fullbytes, &word_num_partialbits,
|
||||
&word_start, &word_step, &word_last, &byte_start, &byte_step);
|
||||
integer_pack_loop_setup(numwords, wordsize, nails, flags,
|
||||
&word_num_fullbytes, &word_num_partialbits,
|
||||
&word_start, &word_step, &word_last, &byte_start, &byte_step);
|
||||
|
||||
wordp = buf + word_start;
|
||||
last_wordp = buf + word_last;
|
||||
wordp = buf + word_start;
|
||||
last_wordp = buf + word_last;
|
||||
|
||||
dd = 0;
|
||||
numbits_in_dd = 0;
|
||||
dd = 0;
|
||||
numbits_in_dd = 0;
|
||||
|
||||
#define PUSH_BITS(data, numbits) \
|
||||
integer_unpack_push_bits(data, numbits, &dd, &numbits_in_dd, &dp)
|
||||
integer_unpack_push_bits(data, numbits, &dd, &numbits_in_dd, &dp)
|
||||
|
||||
while (1) {
|
||||
size_t index_in_word = 0;
|
||||
const unsigned char *bytep = wordp + byte_start;
|
||||
while (index_in_word < word_num_fullbytes) {
|
||||
PUSH_BITS(*bytep, CHAR_BIT);
|
||||
bytep += byte_step;
|
||||
index_in_word++;
|
||||
while (1) {
|
||||
size_t index_in_word = 0;
|
||||
const unsigned char *bytep = wordp + byte_start;
|
||||
while (index_in_word < word_num_fullbytes) {
|
||||
PUSH_BITS(*bytep, CHAR_BIT);
|
||||
bytep += byte_step;
|
||||
index_in_word++;
|
||||
}
|
||||
if (word_num_partialbits) {
|
||||
PUSH_BITS(*bytep & ((1 << word_num_partialbits) - 1), word_num_partialbits);
|
||||
bytep += byte_step;
|
||||
index_in_word++;
|
||||
}
|
||||
|
||||
if (wordp == last_wordp)
|
||||
break;
|
||||
|
||||
wordp += word_step;
|
||||
}
|
||||
if (word_num_partialbits) {
|
||||
PUSH_BITS(*bytep & ((1 << word_num_partialbits) - 1), word_num_partialbits);
|
||||
bytep += byte_step;
|
||||
index_in_word++;
|
||||
}
|
||||
|
||||
if (wordp == last_wordp)
|
||||
break;
|
||||
|
||||
wordp += word_step;
|
||||
}
|
||||
if (dd)
|
||||
*dp++ = (BDIGIT)dd;
|
||||
assert(dp <= de);
|
||||
while (dp < de)
|
||||
*dp++ = 0;
|
||||
if (dd)
|
||||
*dp++ = (BDIGIT)dd;
|
||||
assert(dp <= de);
|
||||
while (dp < de)
|
||||
*dp++ = 0;
|
||||
#undef PUSH_BITS
|
||||
}
|
||||
|
||||
if (flags & INTEGER_PACK_2COMP) {
|
||||
if (num_bdigits == 0) {
|
||||
if (flags & INTEGER_PACK_NEGATIVE)
|
||||
sign = -1;
|
||||
else
|
||||
sign = 0;
|
||||
}
|
||||
else if ((flags & INTEGER_PACK_NEGATIVE) ||
|
||||
(num_bdigits != 0 &&
|
||||
(bdigits[num_bdigits-1] >> (BITSPERDIG - nlp_bits - 1)))) {
|
||||
if (nlp_bits)
|
||||
bdigits[num_bdigits-1] |= (~(BDIGIT)0) << (BITSPERDIG - nlp_bits);
|
||||
bary_2comp(bdigits, num_bdigits);
|
||||
sign = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return sign;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_integer_unpack_internal(const void *words, size_t numwords, size_t wordsize, size_t nails, int flags, int *nlp_bits_ret)
|
||||
static void
|
||||
bary_unpack(BDIGIT *bdigits, size_t num_bdigits, const void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
|
||||
{
|
||||
VALUE result;
|
||||
size_t num_bdigits;
|
||||
int sign = (flags & INTEGER_PACK_NEGATIVE) ? -1 : 1;
|
||||
size_t num_bdigits0;
|
||||
int nlp_bits;
|
||||
|
||||
if (numwords <= (SIZE_MAX - (BITSPERDIG-1)) / CHAR_BIT / wordsize) {
|
||||
num_bdigits = integer_unpack_num_bdigits_small(numwords, wordsize, nails, nlp_bits_ret);
|
||||
#ifdef DEBUG_INTEGER_PACK
|
||||
{
|
||||
int nlp_bits1;
|
||||
size_t num_bdigits1 = integer_unpack_num_bdigits_generic(numwords, wordsize, nails, &nlp_bits1);
|
||||
assert(num_bdigits == num_bdigits1);
|
||||
assert(*nlp_bits_ret == nlp_bits1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
num_bdigits = integer_unpack_num_bdigits_generic(numwords, wordsize, nails, nlp_bits_ret);
|
||||
}
|
||||
if (num_bdigits == 0) {
|
||||
return LONG2FIX(0);
|
||||
}
|
||||
if (LONG_MAX < num_bdigits)
|
||||
rb_raise(rb_eArgError, "too big to unpack as an integer");
|
||||
result = bignew((long)num_bdigits, 0 <= sign);
|
||||
validate_integer_pack_format(numwords, wordsize, nails, flags,
|
||||
INTEGER_PACK_MSWORD_FIRST|
|
||||
INTEGER_PACK_LSWORD_FIRST|
|
||||
INTEGER_PACK_MSBYTE_FIRST|
|
||||
INTEGER_PACK_LSBYTE_FIRST|
|
||||
INTEGER_PACK_NATIVE_BYTE_ORDER|
|
||||
INTEGER_PACK_2COMP|
|
||||
INTEGER_PACK_FORCE_BIGNUM|
|
||||
INTEGER_PACK_NEGATIVE);
|
||||
|
||||
bary_unpack(BDIGITS(result), num_bdigits, words, numwords, wordsize, nails, flags);
|
||||
num_bdigits0 = integer_unpack_num_bdigits(numwords, wordsize, nails, &nlp_bits);
|
||||
|
||||
return result;
|
||||
assert(num_bdigits0 <= num_bdigits);
|
||||
|
||||
bary_unpack_internal(bdigits, num_bdigits, words, numwords, wordsize, nails, flags, nlp_bits);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1345,19 +1397,48 @@ rb_integer_unpack_internal(const void *words, size_t numwords, size_t wordsize,
|
|||
* [nails] number of padding bits in a word.
|
||||
* Most significant nails bits of each word are ignored.
|
||||
* [flags] bitwise or of constants which name starts "INTEGER_PACK_".
|
||||
* It specifies word order and byte order.
|
||||
* [INTEGER_PACK_FORCE_BIGNUM] the result will be a Bignum
|
||||
* even if it is representable as a Fixnum.
|
||||
* [INTEGER_PACK_NEGATIVE] Returns non-positive value.
|
||||
* (Returns non-negative value if not specified.)
|
||||
*
|
||||
* flags:
|
||||
* [INTEGER_PACK_MSWORD_FIRST] Interpret the first word as the most significant word.
|
||||
* [INTEGER_PACK_LSWORD_FIRST] Interpret the first word as the least significant word.
|
||||
* [INTEGER_PACK_MSBYTE_FIRST] Interpret the first byte in a word as the most significant byte in the word.
|
||||
* [INTEGER_PACK_LSBYTE_FIRST] Interpret the first byte in a word as the least significant byte in the word.
|
||||
* [INTEGER_PACK_NATIVE_BYTE_ORDER] INTEGER_PACK_MSBYTE_FIRST or INTEGER_PACK_LSBYTE_FIRST corresponding to the host's endian.
|
||||
* [INTEGER_PACK_2COMP] Use 2's complement representation.
|
||||
* [INTEGER_PACK_LITTLE_ENDIAN] Same as INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_LSBYTE_FIRST
|
||||
* [INTEGER_PACK_BIG_ENDIAN] Same as INTEGER_PACK_MSWORD_FIRST|INTEGER_PACK_MSBYTE_FIRST
|
||||
* [INTEGER_PACK_FORCE_BIGNUM] the result will be a Bignum
|
||||
* even if it is representable as a Fixnum.
|
||||
* [INTEGER_PACK_NEGATIVE] Returns non-positive value.
|
||||
* (Returns non-negative value if not specified.)
|
||||
*
|
||||
* This function returns the imported integer as Fixnum or Bignum.
|
||||
*
|
||||
* The range of the result value depends on INTEGER_PACK_2COMP and INTEGER_PACK_NEGATIVE.
|
||||
*
|
||||
* INTEGER_PACK_2COMP is not set:
|
||||
* 0 <= val < 2**(numwords*(wordsize*CHAR_BIT-nails)) if !INTEGER_PACK_NEGATIVE
|
||||
* -2**(numwords*(wordsize*CHAR_BIT-nails)) < val <= 0 if INTEGER_PACK_NEGATIVE
|
||||
*
|
||||
* INTEGER_PACK_2COMP is set:
|
||||
* -2**(numwords*(wordsize*CHAR_BIT-nails)-1) <= val <= 2**(numwords*(wordsize*CHAR_BIT-nails)-1)-1 if !INTEGER_PACK_NEGATIVE
|
||||
* -2**(numwords*(wordsize*CHAR_BIT-nails)) <= val <= -1 if INTEGER_PACK_NEGATIVE
|
||||
*
|
||||
* INTEGER_PACK_2COMP without INTEGER_PACK_NEGATIVE means sign extension.
|
||||
* INTEGER_PACK_2COMP with INTEGER_PACK_NEGATIVE mean assuming the higher bits are 1.
|
||||
*
|
||||
* Note that this function returns 0 when numwords is zero and
|
||||
* INTEGER_PACK_2COMP is set but INTEGER_PACK_NEGATIVE is not set.
|
||||
*/
|
||||
|
||||
VALUE
|
||||
rb_integer_unpack(const void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
|
||||
{
|
||||
int nlp_bits;
|
||||
VALUE val;
|
||||
size_t num_bdigits;
|
||||
int sign;
|
||||
int nlp_bits;
|
||||
BDIGIT *ds;
|
||||
|
||||
validate_integer_pack_format(numwords, wordsize, nails, flags,
|
||||
INTEGER_PACK_MSWORD_FIRST|
|
||||
|
@ -1365,80 +1446,23 @@ rb_integer_unpack(const void *words, size_t numwords, size_t wordsize, size_t na
|
|||
INTEGER_PACK_MSBYTE_FIRST|
|
||||
INTEGER_PACK_LSBYTE_FIRST|
|
||||
INTEGER_PACK_NATIVE_BYTE_ORDER|
|
||||
INTEGER_PACK_2COMP|
|
||||
INTEGER_PACK_FORCE_BIGNUM|
|
||||
INTEGER_PACK_NEGATIVE);
|
||||
|
||||
val = rb_integer_unpack_internal(words, numwords, wordsize, nails, flags, &nlp_bits);
|
||||
num_bdigits = integer_unpack_num_bdigits(numwords, wordsize, nails, &nlp_bits);
|
||||
|
||||
if (val == LONG2FIX(0)) {
|
||||
if (flags & INTEGER_PACK_FORCE_BIGNUM)
|
||||
return rb_int2big(0);
|
||||
return LONG2FIX(0);
|
||||
}
|
||||
if (flags & INTEGER_PACK_FORCE_BIGNUM)
|
||||
return bigtrunc(val);
|
||||
return bignorm(val);
|
||||
}
|
||||
|
||||
/*
|
||||
* Import an integer into a buffer.
|
||||
*
|
||||
* [words] buffer to import.
|
||||
* [numwords] the size of given buffer as number of words.
|
||||
* [wordsize] the size of word as number of bytes.
|
||||
* [nails] number of padding bits in a word.
|
||||
* Most significant nails bits of each word are ignored.
|
||||
* [flags] bitwise or of constants which name starts "INTEGER_PACK_".
|
||||
* It specifies word order and byte order.
|
||||
* [INTEGER_PACK_FORCE_BIGNUM] the result will be a Bignum
|
||||
* even if it is representable as a Fixnum.
|
||||
* [INTEGER_PACK_NEGATIVE] Assume the higher bits are 1.
|
||||
* (If INTEGER_PACK_NEGATIVE is not specified, the higher bits are
|
||||
* assumed same as the most significant bit.
|
||||
* i.e. sign extension is applied.)
|
||||
*
|
||||
* This function returns the imported integer as Fixnum or Bignum.
|
||||
*/
|
||||
VALUE
|
||||
rb_integer_unpack_2comp(const void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
|
||||
{
|
||||
VALUE val;
|
||||
int nlp_bits;
|
||||
|
||||
validate_integer_pack_format(numwords, wordsize, nails, flags,
|
||||
INTEGER_PACK_MSWORD_FIRST|
|
||||
INTEGER_PACK_LSWORD_FIRST|
|
||||
INTEGER_PACK_MSBYTE_FIRST|
|
||||
INTEGER_PACK_LSBYTE_FIRST|
|
||||
INTEGER_PACK_NATIVE_BYTE_ORDER|
|
||||
INTEGER_PACK_FORCE_BIGNUM|
|
||||
INTEGER_PACK_NEGATIVE);
|
||||
|
||||
val = rb_integer_unpack_internal(words, numwords, wordsize, nails,
|
||||
(flags & (INTEGER_PACK_WORDORDER_MASK|INTEGER_PACK_BYTEORDER_MASK) |
|
||||
INTEGER_PACK_FORCE_BIGNUM),
|
||||
&nlp_bits);
|
||||
|
||||
if (val == LONG2FIX(0)) {
|
||||
/* num_bdigits == 0 i.e. num_bits == 0 */
|
||||
int v;
|
||||
if (flags & INTEGER_PACK_NEGATIVE)
|
||||
v = -1;
|
||||
else
|
||||
v = 0;
|
||||
if (flags & INTEGER_PACK_FORCE_BIGNUM)
|
||||
return rb_int2big(v);
|
||||
else
|
||||
return LONG2FIX(v);
|
||||
}
|
||||
else if ((flags & INTEGER_PACK_NEGATIVE) ||
|
||||
(RBIGNUM_LEN(val) != 0 &&
|
||||
(RBIGNUM_DIGITS(val)[RBIGNUM_LEN(val)-1] >> (BITSPERDIG - nlp_bits - 1)))) {
|
||||
if (nlp_bits)
|
||||
RBIGNUM_DIGITS(val)[RBIGNUM_LEN(val)-1] |= (~(BDIGIT)0) << (BITSPERDIG - nlp_bits);
|
||||
rb_big_2comp(val);
|
||||
RBIGNUM_SET_SIGN(val, 0);
|
||||
if (LONG_MAX < num_bdigits)
|
||||
rb_raise(rb_eArgError, "too big to unpack as an integer");
|
||||
val = bignew((long)num_bdigits, 0);
|
||||
ds = BDIGITS(val);
|
||||
sign = bary_unpack_internal(ds, num_bdigits, words, numwords, wordsize, nails, flags, nlp_bits);
|
||||
|
||||
if ((flags & INTEGER_PACK_2COMP) && num_bdigits == 0 && sign < 0) {
|
||||
rb_big_resize(val, 1);
|
||||
ds[0] = 1;
|
||||
}
|
||||
RBIGNUM_SET_SIGN(val, 0 <= sign);
|
||||
|
||||
if (flags & INTEGER_PACK_FORCE_BIGNUM)
|
||||
return bigtrunc(val);
|
||||
|
|
|
@ -45,23 +45,12 @@ rb_integer_unpack_m(VALUE klass, VALUE buf, VALUE numwords, VALUE wordsize, VALU
|
|||
NUM2SIZET(nails), NUM2INT(flags));
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_integer_unpack_2comp_m(VALUE klass, VALUE buf, VALUE numwords, VALUE wordsize, VALUE nails, VALUE flags)
|
||||
{
|
||||
StringValue(buf);
|
||||
|
||||
return rb_integer_unpack_2comp(RSTRING_PTR(buf),
|
||||
NUM2SIZET(numwords), NUM2SIZET(wordsize),
|
||||
NUM2SIZET(nails), NUM2INT(flags));
|
||||
}
|
||||
|
||||
void
|
||||
Init_pack(VALUE klass)
|
||||
{
|
||||
rb_define_method(rb_cInteger, "test_pack_raw", rb_integer_pack_raw_m, 5);
|
||||
rb_define_method(rb_cInteger, "test_pack", rb_integer_pack_m, 4);
|
||||
rb_define_singleton_method(rb_cInteger, "test_unpack", rb_integer_unpack_m, 5);
|
||||
rb_define_singleton_method(rb_cInteger, "test_unpack_2comp", rb_integer_unpack_2comp_m, 5);
|
||||
rb_define_const(rb_cInteger, "INTEGER_PACK_MSWORD_FIRST", INT2NUM(INTEGER_PACK_MSWORD_FIRST));
|
||||
rb_define_const(rb_cInteger, "INTEGER_PACK_LSWORD_FIRST", INT2NUM(INTEGER_PACK_LSWORD_FIRST));
|
||||
rb_define_const(rb_cInteger, "INTEGER_PACK_MSBYTE_FIRST", INT2NUM(INTEGER_PACK_MSBYTE_FIRST));
|
||||
|
|
|
@ -451,7 +451,6 @@ VALUE rb_thread_io_blocking_region(rb_blocking_function_t *func, void *data1, in
|
|||
/* bignum.c */
|
||||
int rb_integer_pack(VALUE val, void *words, size_t numwords, size_t wordsize, size_t nails, int flags);
|
||||
VALUE rb_integer_unpack(const void *words, size_t numwords, size_t wordsize, size_t nails, int flags);
|
||||
VALUE rb_integer_unpack_2comp(const void *words, size_t numwords, size_t wordsize, size_t nails, int flags);
|
||||
|
||||
/* io.c */
|
||||
void rb_maygvl_fd_fix_cloexec(int fd);
|
||||
|
|
5
pack.c
5
pack.c
|
@ -1731,9 +1731,8 @@ pack_unpack(VALUE str, VALUE fmt)
|
|||
int flags = bigendian_p ? INTEGER_PACK_BIG_ENDIAN : INTEGER_PACK_LITTLE_ENDIAN;
|
||||
VALUE val;
|
||||
if (signed_p)
|
||||
val = rb_integer_unpack_2comp(s, integer_size, 1, 0, flags);
|
||||
else
|
||||
val = rb_integer_unpack(s, integer_size, 1, 0, flags);
|
||||
flags |= INTEGER_PACK_2COMP;
|
||||
val = rb_integer_unpack(s, integer_size, 1, 0, flags);
|
||||
UNPACK_PUSH(val);
|
||||
s += integer_size;
|
||||
}
|
||||
|
|
|
@ -164,34 +164,34 @@ class TestBignum < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_unpack2comp_single_byte
|
||||
assert_equal(-128, Integer.test_unpack_2comp("\x80", 1, 1, 0, BIG_ENDIAN))
|
||||
assert_equal( -2, Integer.test_unpack_2comp("\xFE", 1, 1, 0, BIG_ENDIAN))
|
||||
assert_equal( -1, Integer.test_unpack_2comp("\xFF", 1, 1, 0, BIG_ENDIAN))
|
||||
assert_equal( 0, Integer.test_unpack_2comp("\x00", 1, 1, 0, BIG_ENDIAN))
|
||||
assert_equal( 1, Integer.test_unpack_2comp("\x01", 1, 1, 0, BIG_ENDIAN))
|
||||
assert_equal( 2, Integer.test_unpack_2comp("\x02", 1, 1, 0, BIG_ENDIAN))
|
||||
assert_equal( 127, Integer.test_unpack_2comp("\x7F", 1, 1, 0, BIG_ENDIAN))
|
||||
assert_equal(-128, Integer.test_unpack("\x80", 1, 1, 0, TWOCOMP|BIG_ENDIAN))
|
||||
assert_equal( -2, Integer.test_unpack("\xFE", 1, 1, 0, TWOCOMP|BIG_ENDIAN))
|
||||
assert_equal( -1, Integer.test_unpack("\xFF", 1, 1, 0, TWOCOMP|BIG_ENDIAN))
|
||||
assert_equal( 0, Integer.test_unpack("\x00", 1, 1, 0, TWOCOMP|BIG_ENDIAN))
|
||||
assert_equal( 1, Integer.test_unpack("\x01", 1, 1, 0, TWOCOMP|BIG_ENDIAN))
|
||||
assert_equal( 2, Integer.test_unpack("\x02", 1, 1, 0, TWOCOMP|BIG_ENDIAN))
|
||||
assert_equal( 127, Integer.test_unpack("\x7F", 1, 1, 0, TWOCOMP|BIG_ENDIAN))
|
||||
end
|
||||
|
||||
def test_unpack2comp_sequence_of_ff
|
||||
assert_equal(-1, Integer.test_unpack_2comp("\xFF"*2, 2, 1, 0, BIG_ENDIAN))
|
||||
assert_equal(-1, Integer.test_unpack_2comp("\xFF"*3, 3, 1, 0, BIG_ENDIAN))
|
||||
assert_equal(-1, Integer.test_unpack_2comp("\xFF"*4, 4, 1, 0, BIG_ENDIAN))
|
||||
assert_equal(-1, Integer.test_unpack_2comp("\xFF"*5, 5, 1, 0, BIG_ENDIAN))
|
||||
assert_equal(-1, Integer.test_unpack_2comp("\xFF"*6, 6, 1, 0, BIG_ENDIAN))
|
||||
assert_equal(-1, Integer.test_unpack_2comp("\xFF"*7, 7, 1, 0, BIG_ENDIAN))
|
||||
assert_equal(-1, Integer.test_unpack_2comp("\xFF"*8, 8, 1, 0, BIG_ENDIAN))
|
||||
assert_equal(-1, Integer.test_unpack_2comp("\xFF"*9, 9, 1, 0, BIG_ENDIAN))
|
||||
assert_equal(-1, Integer.test_unpack("\xFF"*2, 2, 1, 0, TWOCOMP|BIG_ENDIAN))
|
||||
assert_equal(-1, Integer.test_unpack("\xFF"*3, 3, 1, 0, TWOCOMP|BIG_ENDIAN))
|
||||
assert_equal(-1, Integer.test_unpack("\xFF"*4, 4, 1, 0, TWOCOMP|BIG_ENDIAN))
|
||||
assert_equal(-1, Integer.test_unpack("\xFF"*5, 5, 1, 0, TWOCOMP|BIG_ENDIAN))
|
||||
assert_equal(-1, Integer.test_unpack("\xFF"*6, 6, 1, 0, TWOCOMP|BIG_ENDIAN))
|
||||
assert_equal(-1, Integer.test_unpack("\xFF"*7, 7, 1, 0, TWOCOMP|BIG_ENDIAN))
|
||||
assert_equal(-1, Integer.test_unpack("\xFF"*8, 8, 1, 0, TWOCOMP|BIG_ENDIAN))
|
||||
assert_equal(-1, Integer.test_unpack("\xFF"*9, 9, 1, 0, TWOCOMP|BIG_ENDIAN))
|
||||
end
|
||||
|
||||
def test_unpack2comp_negative_single_byte
|
||||
assert_equal(-256, Integer.test_unpack_2comp("\x00", 1, 1, 0, BIG_ENDIAN|NEGATIVE))
|
||||
assert_equal(-255, Integer.test_unpack_2comp("\x01", 1, 1, 0, BIG_ENDIAN|NEGATIVE))
|
||||
assert_equal(-254, Integer.test_unpack_2comp("\x02", 1, 1, 0, BIG_ENDIAN|NEGATIVE))
|
||||
assert_equal(-129, Integer.test_unpack_2comp("\x7F", 1, 1, 0, BIG_ENDIAN|NEGATIVE))
|
||||
assert_equal(-128, Integer.test_unpack_2comp("\x80", 1, 1, 0, BIG_ENDIAN|NEGATIVE))
|
||||
assert_equal( -2, Integer.test_unpack_2comp("\xFE", 1, 1, 0, BIG_ENDIAN|NEGATIVE))
|
||||
assert_equal( -1, Integer.test_unpack_2comp("\xFF", 1, 1, 0, BIG_ENDIAN|NEGATIVE))
|
||||
assert_equal(-256, Integer.test_unpack("\x00", 1, 1, 0, TWOCOMP|BIG_ENDIAN|NEGATIVE))
|
||||
assert_equal(-255, Integer.test_unpack("\x01", 1, 1, 0, TWOCOMP|BIG_ENDIAN|NEGATIVE))
|
||||
assert_equal(-254, Integer.test_unpack("\x02", 1, 1, 0, TWOCOMP|BIG_ENDIAN|NEGATIVE))
|
||||
assert_equal(-129, Integer.test_unpack("\x7F", 1, 1, 0, TWOCOMP|BIG_ENDIAN|NEGATIVE))
|
||||
assert_equal(-128, Integer.test_unpack("\x80", 1, 1, 0, TWOCOMP|BIG_ENDIAN|NEGATIVE))
|
||||
assert_equal( -2, Integer.test_unpack("\xFE", 1, 1, 0, TWOCOMP|BIG_ENDIAN|NEGATIVE))
|
||||
assert_equal( -1, Integer.test_unpack("\xFF", 1, 1, 0, TWOCOMP|BIG_ENDIAN|NEGATIVE))
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue