1
0
Fork 0
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:
akr 2013-06-16 12:59:26 +00:00
parent ecabbf1bf6
commit 50794b3222
6 changed files with 202 additions and 174 deletions

View file

@ -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
View file

@ -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);

View file

@ -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));

View file

@ -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
View file

@ -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;
}

View file

@ -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