1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* internal.h (INTEGER_PACK_2COMP): Defined.

(rb_integer_pack_2comp): Removed.

* bignum.c (bary_pack): Support INTEGER_PACK_2COMP.
  (rb_integer_pack): Invoke bary_pack directly.
  (rb_integer_pack_2comp): Removed.
  (rb_integer_pack_internal): Ditto.
  (absint_numwords_generic): Follow the above change.

* pack.c (pack_pack): Ditto.

* sprintf.c (rb_str_format): Ditto.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41336 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
akr 2013-06-16 09:53:45 +00:00
parent fc3fbc143c
commit ecabbf1bf6
7 changed files with 160 additions and 168 deletions

View file

@ -1,3 +1,18 @@
Sun Jun 16 18:41:42 2013 Tanaka Akira <akr@fsij.org>
* internal.h (INTEGER_PACK_2COMP): Defined.
(rb_integer_pack_2comp): Removed.
* bignum.c (bary_pack): Support INTEGER_PACK_2COMP.
(rb_integer_pack): Invoke bary_pack directly.
(rb_integer_pack_2comp): Removed.
(rb_integer_pack_internal): Ditto.
(absint_numwords_generic): Follow the above change.
* pack.c (pack_pack): Ditto.
* sprintf.c (rb_str_format): Ditto.
Sun Jun 16 17:48:14 2013 Tanaka Akira <akr@fsij.org>
* bignum.c (absint_numwords_generic): rb_funcall invocations removed.

221
bignum.c
View file

@ -63,7 +63,7 @@ static void bary_mul(BDIGIT *zds, size_t zl, BDIGIT *xds, size_t xl, BDIGIT *yds
static void bary_sub(BDIGIT *zds, size_t zn, BDIGIT *xds, size_t xn, BDIGIT *yds, size_t yn);
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, int overflow_2comp);
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);
#define BIGNUM_DEBUG 0
#if BIGNUM_DEBUG
@ -634,11 +634,11 @@ absint_numwords_generic(size_t numbytes, int nlz_bits_in_msbyte, size_t word_num
else {
bary_add(BARY_ARGS(div_bary), BARY_ARGS(div_bary), BARY_ARGS(one));
bary_pack(+1, BARY_ARGS(mod_bary), &mod, 1, sizeof(mod), 0,
INTEGER_PACK_NATIVE_BYTE_ORDER, 0);
INTEGER_PACK_NATIVE_BYTE_ORDER);
nlz_bits = word_numbits - mod;
}
sign = bary_pack(+1, BARY_ARGS(div_bary), &numwords, 1, sizeof(numwords), 0,
INTEGER_PACK_NATIVE_BYTE_ORDER, 0);
INTEGER_PACK_NATIVE_BYTE_ORDER);
if (sign == 2)
return (size_t)-1;
@ -888,7 +888,7 @@ integer_pack_take_lowbits(int n, BDIGIT_DBL *ddp, int *numbits_in_dd_p)
}
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, int overflow_2comp)
bary_pack(int sign, BDIGIT *ds, size_t num_bdigits, void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
{
BDIGIT *dp, *de;
unsigned char *buf, *bufend;
@ -901,8 +901,8 @@ bary_pack(int sign, BDIGIT *ds, size_t num_bdigits, void *words, size_t numwords
INTEGER_PACK_LSWORD_FIRST|
INTEGER_PACK_MSBYTE_FIRST|
INTEGER_PACK_LSBYTE_FIRST|
INTEGER_PACK_NATIVE_BYTE_ORDER);
INTEGER_PACK_NATIVE_BYTE_ORDER|
INTEGER_PACK_2COMP);
while (dp < de && de[-1] == 0)
de--;
@ -915,7 +915,7 @@ bary_pack(int sign, BDIGIT *ds, size_t num_bdigits, void *words, size_t numwords
if (buf == bufend) {
/* overflow if non-zero*/
if (!overflow_2comp || 0 <= sign)
if (!(flags & INTEGER_PACK_2COMP) || 0 <= sign)
sign *= 2;
else {
if (de - dp == 1 && dp[0] == 1)
@ -989,7 +989,7 @@ bary_pack(int sign, BDIGIT *ds, size_t num_bdigits, void *words, size_t numwords
}
else if (dd == 1) {
/* 2**(numwords*(wordsize*CHAR_BIT-nails)) <= abs(val) < 2**(numwords*(wordsize*CHAR_BIT-nails)+1) */
if (!overflow_2comp || 0 <= sign)
if (!(flags & INTEGER_PACK_2COMP) || 0 <= sign)
sign *= 2;
else { /* overflow_2comp && sign == -1 */
/* test lower bits are all zero. */
@ -1005,112 +1005,7 @@ bary_pack(int sign, BDIGIT *ds, size_t num_bdigits, void *words, size_t numwords
}
}
return sign;
#undef FILL_DD
#undef TAKE_LOWBITS
}
static int
rb_integer_pack_internal(VALUE val, void *words, size_t numwords, size_t wordsize, size_t nails, int flags, int overflow_2comp)
{
int sign;
BDIGIT *ds;
size_t num_bdigits;
BDIGIT fixbuf[(sizeof(long) + SIZEOF_BDIGITS - 1) / SIZEOF_BDIGITS];
RB_GC_GUARD(val) = rb_to_int(val);
if (FIXNUM_P(val)) {
long v = FIX2LONG(val);
if (v < 0) {
sign = -1;
v = -v;
}
else {
sign = 1;
}
#if SIZEOF_BDIGITS == SIZEOF_LONG
fixbuf[0] = v;
#else
{
int i;
for (i = 0; i < numberof(fixbuf); i++) {
fixbuf[i] = (BDIGIT)(v & ((1L << (SIZEOF_BDIGITS * CHAR_BIT)) - 1));
v >>= SIZEOF_BDIGITS * CHAR_BIT;
}
}
#endif
ds = fixbuf;
num_bdigits = numberof(fixbuf);
}
else {
sign = RBIGNUM_POSITIVE_P(val) ? 1 : -1;
ds = BDIGITS(val);
num_bdigits = RBIGNUM_LEN(val);
}
return bary_pack(sign, ds, num_bdigits, words, numwords, wordsize, nails, flags, overflow_2comp);
}
/*
* Export an integer into a buffer.
*
* This function fills the buffer specified by _words_ and _numwords_ as
* abs(val) in the format specified by _wordsize_, _nails_ and _flags_.
*
* [val] Fixnum, Bignum or another integer like object which has to_int method.
* [words] buffer to export abs(val).
* [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 filled by zero.
* [flags] bitwise or of constants which name starts "INTEGER_PACK_".
* It specifies word order and byte order.
*
* This function returns the signedness and overflow condition as follows:
* -2 : negative overflow. val <= -2**(numwords*(wordsize*CHAR_BIT-nails))
* -1 : negative without overflow. -2**(numwords*(wordsize*CHAR_BIT-nails)) < val < 0
* 0 : zero. val == 0
* 1 : positive without overflow. 0 < val < 2**(numwords*(wordsize*CHAR_BIT-nails))
* 2 : positive overflow. 2**(numwords*(wordsize*CHAR_BIT-nails)) <= val
*
* The least significant words of abs(val) are filled in the buffer when overflow occur.
*/
int
rb_integer_pack(VALUE val, void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
{
return rb_integer_pack_internal(val, words, numwords, wordsize, nails, flags, 0);
}
/*
* Export an integer into a buffer in 2's comlement representation.
*
* This function is similar to rb_integer_pack_2comp but
* the number is filled as 2's comlement representation and
* return value is bit different (because overflow condition
* is differnt between absolute value and 2's comlement).
*
* This function returns the signedness and overflow condition as follows:
* -2 : negative overflow. val < -2**(numwords*(wordsize*CHAR_BIT-nails))
* -1 : negative without overflow. -2**(numwords*(wordsize*CHAR_BIT-nails)) <= val < 0
* 0 : zero. val == 0
* 1 : positive without overflow. 0 < val < 2**(numwords*(wordsize*CHAR_BIT-nails))
* 2 : positive overflow. 2**(numwords*(wordsize*CHAR_BIT-nails)) <= val
*
* rb_integer_pack_2comp returns -1 for val == -2**(numwords*(wordsize*CHAR_BIT-nails)) but
* rb_integer_pack returns -2.
*
*/
int
rb_integer_pack_2comp(VALUE val, void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
{
int sign;
sign = rb_integer_pack_internal(val, words, numwords, wordsize, nails, flags, 1);
if (sign < 0 && numwords != 0) {
if ((flags & INTEGER_PACK_2COMP) && (sign < 0 && numwords != 0)) {
unsigned char *buf;
int word_num_partialbits;
@ -1163,6 +1058,104 @@ rb_integer_pack_2comp(VALUE val, void *words, size_t numwords, size_t wordsize,
}
return sign;
#undef FILL_DD
#undef TAKE_LOWBITS
}
/*
* Export an integer into a buffer.
*
* This function fills the buffer specified by _words_ and _numwords_ as
* val in the format specified by _wordsize_, _nails_ and _flags_.
*
* [val] Fixnum, Bignum or another integer like object which has to_int method.
* [words] buffer to export abs(val).
* [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 filled by zero.
* [flags] bitwise or of constants which name starts "INTEGER_PACK_".
*
* flags:
* [INTEGER_PACK_MSWORD_FIRST] Store the most significant word as the first word.
* [INTEGER_PACK_LSWORD_FIRST] Store the least significant word as the first word.
* [INTEGER_PACK_MSBYTE_FIRST] Store the most significant byte in a word as the first byte in the word.
* [INTEGER_PACK_LSBYTE_FIRST] Store the least significant byte in a word as the first 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
*
* This function fills the buffer specified by _words_
* as abs(val) if INTEGER_PACK_2COMP is not specified in _flags_.
* If INTEGER_PACK_2COMP is specified, 2's complement representation of val is
* filled in the buffer.
*
* This function returns the signedness and overflow condition.
* The overflow condition depends on INTEGER_PACK_2COMP.
*
* INTEGER_PACK_2COMP is not specified:
* -2 : negative overflow. val <= -2**(numwords*(wordsize*CHAR_BIT-nails))
* -1 : negative without overflow. -2**(numwords*(wordsize*CHAR_BIT-nails)) < val < 0
* 0 : zero. val == 0
* 1 : positive without overflow. 0 < val < 2**(numwords*(wordsize*CHAR_BIT-nails))
* 2 : positive overflow. 2**(numwords*(wordsize*CHAR_BIT-nails)) <= val
*
* INTEGER_PACK_2COMP is specified:
* -2 : negative overflow. val < -2**(numwords*(wordsize*CHAR_BIT-nails))
* -1 : negative without overflow. -2**(numwords*(wordsize*CHAR_BIT-nails)) <= val < 0
* 0 : zero. val == 0
* 1 : positive without overflow. 0 < val < 2**(numwords*(wordsize*CHAR_BIT-nails))
* 2 : positive overflow. 2**(numwords*(wordsize*CHAR_BIT-nails)) <= val
*
* The value, -2**(numwords*(wordsize*CHAR_BIT-nails)), is representable
* in 2's complement representation but not representable in absolute value.
* So -1 is returned for the value if INTEGER_PACK_2COMP is specified
* but returns -2 if INTEGER_PACK_2COMP is not specified.
*
* The least significant words are filled in the buffer when overflow occur.
*/
int
rb_integer_pack(VALUE val, void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
{
int sign;
BDIGIT *ds;
size_t num_bdigits;
BDIGIT fixbuf[(sizeof(long) + SIZEOF_BDIGITS - 1) / SIZEOF_BDIGITS];
RB_GC_GUARD(val) = rb_to_int(val);
if (FIXNUM_P(val)) {
long v = FIX2LONG(val);
if (v < 0) {
sign = -1;
v = -v;
}
else {
sign = 1;
}
#if SIZEOF_BDIGITS == SIZEOF_LONG
fixbuf[0] = v;
#else
{
int i;
for (i = 0; i < numberof(fixbuf); i++) {
fixbuf[i] = (BDIGIT)(v & ((1L << (SIZEOF_BDIGITS * CHAR_BIT)) - 1));
v >>= SIZEOF_BDIGITS * CHAR_BIT;
}
}
#endif
ds = fixbuf;
num_bdigits = numberof(fixbuf);
}
else {
sign = RBIGNUM_POSITIVE_P(val) ? 1 : -1;
ds = BDIGITS(val);
num_bdigits = RBIGNUM_LEN(val);
}
return bary_pack(sign, ds, num_bdigits, words, numwords, wordsize, nails, flags);
}
static size_t

View file

@ -35,24 +35,6 @@ rb_integer_pack_m(VALUE val, VALUE numwords_arg, VALUE wordsize_arg, VALUE nails
return rb_assoc_new(INT2NUM(sign), buf);
}
static VALUE
rb_integer_pack_2comp_m(VALUE val, VALUE numwords_arg, VALUE wordsize_arg, VALUE nails, VALUE flags)
{
int sign;
size_t numwords = NUM2SIZET(numwords_arg);
size_t wordsize = NUM2SIZET(wordsize_arg);
VALUE buf;
if (numwords != 0 && wordsize != 0 && LONG_MAX / wordsize < numwords)
rb_raise(rb_eArgError, "too big numwords * wordsize");
buf = rb_str_new(NULL, numwords * wordsize);
sign = rb_integer_pack_2comp(val,
RSTRING_PTR(buf), numwords,
wordsize, NUM2SIZET(nails), NUM2INT(flags));
return rb_assoc_new(INT2NUM(sign), buf);
}
static VALUE
rb_integer_unpack_m(VALUE klass, VALUE buf, VALUE numwords, VALUE wordsize, VALUE nails, VALUE flags)
{
@ -78,7 +60,6 @@ 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_method(rb_cInteger, "test_pack_2comp", rb_integer_pack_2comp_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));
@ -86,6 +67,7 @@ Init_pack(VALUE klass)
rb_define_const(rb_cInteger, "INTEGER_PACK_MSBYTE_FIRST", INT2NUM(INTEGER_PACK_MSBYTE_FIRST));
rb_define_const(rb_cInteger, "INTEGER_PACK_LSBYTE_FIRST", INT2NUM(INTEGER_PACK_LSBYTE_FIRST));
rb_define_const(rb_cInteger, "INTEGER_PACK_NATIVE_BYTE_ORDER", INT2NUM(INTEGER_PACK_NATIVE_BYTE_ORDER));
rb_define_const(rb_cInteger, "INTEGER_PACK_2COMP", INT2NUM(INTEGER_PACK_2COMP));
rb_define_const(rb_cInteger, "INTEGER_PACK_LITTLE_ENDIAN", INT2NUM(INTEGER_PACK_LITTLE_ENDIAN));
rb_define_const(rb_cInteger, "INTEGER_PACK_BIG_ENDIAN", INT2NUM(INTEGER_PACK_BIG_ENDIAN));
rb_define_const(rb_cInteger, "INTEGER_PACK_FORCE_BIGNUM", INT2NUM(INTEGER_PACK_FORCE_BIGNUM));

View file

@ -61,6 +61,7 @@ extern "C" {
#define INTEGER_PACK_MSBYTE_FIRST 0x10
#define INTEGER_PACK_LSBYTE_FIRST 0x20
#define INTEGER_PACK_NATIVE_BYTE_ORDER 0x40
#define INTEGER_PACK_2COMP 0x80
/* For rb_integer_unpack: */
#define INTEGER_PACK_FORCE_BIGNUM 0x100
#define INTEGER_PACK_NEGATIVE 0x200
@ -450,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);
int rb_integer_pack_2comp(VALUE val, 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 */

5
pack.c
View file

@ -799,8 +799,9 @@ pack_pack(VALUE ary, VALUE fmt)
char intbuf[MAX_INTEGER_PACK_SIZE];
from = NEXTFROM;
rb_integer_pack_2comp(from, intbuf, integer_size, 1, 0,
bigendian_p ? INTEGER_PACK_BIG_ENDIAN : INTEGER_PACK_LITTLE_ENDIAN);
rb_integer_pack(from, intbuf, integer_size, 1, 0,
INTEGER_PACK_2COMP |
(bigendian_p ? INTEGER_PACK_BIG_ENDIAN : INTEGER_PACK_LITTLE_ENDIAN));
rb_str_buf_cat(res, intbuf, integer_size);
}
break;

View file

@ -856,8 +856,8 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt)
(!bignum ? v < 0 : RBIGNUM_NEGATIVE_P(val))))
numdigits++;
tmp = rb_str_new(NULL, numdigits);
valsign = rb_integer_pack_2comp(val, RSTRING_PTR(tmp), RSTRING_LEN(tmp),
1, CHAR_BIT-numbits, INTEGER_PACK_BIG_ENDIAN);
valsign = rb_integer_pack(val, RSTRING_PTR(tmp), RSTRING_LEN(tmp),
1, CHAR_BIT-numbits, INTEGER_PACK_2COMP | INTEGER_PACK_BIG_ENDIAN);
for (i = 0; i < RSTRING_LEN(tmp); i++)
RSTRING_PTR(tmp)[i] = ruby_digitmap[((unsigned char *)RSTRING_PTR(tmp))[i]];
s = RSTRING_PTR(tmp);

View file

@ -11,6 +11,7 @@ class TestBignum < Test::Unit::TestCase
MSBYTE_FIRST = Integer::INTEGER_PACK_MSBYTE_FIRST
LSBYTE_FIRST = Integer::INTEGER_PACK_LSBYTE_FIRST
NATIVE_BYTE_ORDER = Integer::INTEGER_PACK_NATIVE_BYTE_ORDER
TWOCOMP = Integer::INTEGER_PACK_2COMP
LITTLE_ENDIAN = Integer::INTEGER_PACK_LITTLE_ENDIAN
BIG_ENDIAN = Integer::INTEGER_PACK_BIG_ENDIAN
NEGATIVE = Integer::INTEGER_PACK_NEGATIVE
@ -74,47 +75,47 @@ class TestBignum < Test::Unit::TestCase
end
def test_pack2comp_zero
assert_equal([0, ""], 0.test_pack_2comp(0, 1, 0, BIG_ENDIAN))
assert_equal([0, ""], 0.test_pack(0, 1, 0, TWOCOMP|BIG_ENDIAN))
end
def test_pack2comp_emptybuf
assert_equal([-2, ""], (-3).test_pack_2comp(0, 1, 0, BIG_ENDIAN))
assert_equal([-2, ""], (-2).test_pack_2comp(0, 1, 0, BIG_ENDIAN))
assert_equal([-1, ""], (-1).test_pack_2comp(0, 1, 0, BIG_ENDIAN))
assert_equal([ 0, ""], 0.test_pack_2comp(0, 1, 0, BIG_ENDIAN))
assert_equal([+2, ""], 1.test_pack_2comp(0, 1, 0, BIG_ENDIAN))
assert_equal([+2, ""], 2.test_pack_2comp(0, 1, 0, BIG_ENDIAN))
assert_equal([-2, ""], (-3).test_pack(0, 1, 0, TWOCOMP|BIG_ENDIAN))
assert_equal([-2, ""], (-2).test_pack(0, 1, 0, TWOCOMP|BIG_ENDIAN))
assert_equal([-1, ""], (-1).test_pack(0, 1, 0, TWOCOMP|BIG_ENDIAN))
assert_equal([ 0, ""], 0.test_pack(0, 1, 0, TWOCOMP|BIG_ENDIAN))
assert_equal([+2, ""], 1.test_pack(0, 1, 0, TWOCOMP|BIG_ENDIAN))
assert_equal([+2, ""], 2.test_pack(0, 1, 0, TWOCOMP|BIG_ENDIAN))
end
def test_pack2comp_nearly_zero
assert_equal([-1, "\xFE"], (-2).test_pack_2comp(1, 1, 0, BIG_ENDIAN))
assert_equal([-1, "\xFF"], (-1).test_pack_2comp(1, 1, 0, BIG_ENDIAN))
assert_equal([ 0, "\x00"], 0.test_pack_2comp(1, 1, 0, BIG_ENDIAN))
assert_equal([+1, "\x01"], 1.test_pack_2comp(1, 1, 0, BIG_ENDIAN))
assert_equal([+1, "\x02"], 2.test_pack_2comp(1, 1, 0, BIG_ENDIAN))
assert_equal([-1, "\xFE"], (-2).test_pack(1, 1, 0, TWOCOMP|BIG_ENDIAN))
assert_equal([-1, "\xFF"], (-1).test_pack(1, 1, 0, TWOCOMP|BIG_ENDIAN))
assert_equal([ 0, "\x00"], 0.test_pack(1, 1, 0, TWOCOMP|BIG_ENDIAN))
assert_equal([+1, "\x01"], 1.test_pack(1, 1, 0, TWOCOMP|BIG_ENDIAN))
assert_equal([+1, "\x02"], 2.test_pack(1, 1, 0, TWOCOMP|BIG_ENDIAN))
end
def test_pack2comp_overflow
assert_equal([-2, "\xF"], (-0x11).test_pack_2comp(1, 1, 4, BIG_ENDIAN))
assert_equal([-1, "\x0"], (-0x10).test_pack_2comp(1, 1, 4, BIG_ENDIAN))
assert_equal([-1, "\x1"], (-0x0F).test_pack_2comp(1, 1, 4, BIG_ENDIAN))
assert_equal([+1, "\xF"], (+0x0F).test_pack_2comp(1, 1, 4, BIG_ENDIAN))
assert_equal([+2, "\x0"], (+0x10).test_pack_2comp(1, 1, 4, BIG_ENDIAN))
assert_equal([+2, "\x1"], (+0x11).test_pack_2comp(1, 1, 4, BIG_ENDIAN))
assert_equal([-2, "\xF"], (-0x11).test_pack(1, 1, 4, TWOCOMP|BIG_ENDIAN))
assert_equal([-1, "\x0"], (-0x10).test_pack(1, 1, 4, TWOCOMP|BIG_ENDIAN))
assert_equal([-1, "\x1"], (-0x0F).test_pack(1, 1, 4, TWOCOMP|BIG_ENDIAN))
assert_equal([+1, "\xF"], (+0x0F).test_pack(1, 1, 4, TWOCOMP|BIG_ENDIAN))
assert_equal([+2, "\x0"], (+0x10).test_pack(1, 1, 4, TWOCOMP|BIG_ENDIAN))
assert_equal([+2, "\x1"], (+0x11).test_pack(1, 1, 4, TWOCOMP|BIG_ENDIAN))
assert_equal([-2, "\xFF"], (-0x101).test_pack_2comp(1, 1, 0, BIG_ENDIAN))
assert_equal([-1, "\x00"], (-0x100).test_pack_2comp(1, 1, 0, BIG_ENDIAN))
assert_equal([-1, "\x01"], (-0x0FF).test_pack_2comp(1, 1, 0, BIG_ENDIAN))
assert_equal([+1, "\xFF"], (+0x0FF).test_pack_2comp(1, 1, 0, BIG_ENDIAN))
assert_equal([+2, "\x00"], (+0x100).test_pack_2comp(1, 1, 0, BIG_ENDIAN))
assert_equal([+2, "\x01"], (+0x101).test_pack_2comp(1, 1, 0, BIG_ENDIAN))
assert_equal([-2, "\xFF"], (-0x101).test_pack(1, 1, 0, TWOCOMP|BIG_ENDIAN))
assert_equal([-1, "\x00"], (-0x100).test_pack(1, 1, 0, TWOCOMP|BIG_ENDIAN))
assert_equal([-1, "\x01"], (-0x0FF).test_pack(1, 1, 0, TWOCOMP|BIG_ENDIAN))
assert_equal([+1, "\xFF"], (+0x0FF).test_pack(1, 1, 0, TWOCOMP|BIG_ENDIAN))
assert_equal([+2, "\x00"], (+0x100).test_pack(1, 1, 0, TWOCOMP|BIG_ENDIAN))
assert_equal([+2, "\x01"], (+0x101).test_pack(1, 1, 0, TWOCOMP|BIG_ENDIAN))
assert_equal([-2, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"], (-0x10000000000000001).test_pack_2comp(2, 4, 0, BIG_ENDIAN))
assert_equal([-1, "\x00\x00\x00\x00\x00\x00\x00\x00"], (-0x10000000000000000).test_pack_2comp(2, 4, 0, BIG_ENDIAN))
assert_equal([-1, "\x00\x00\x00\x00\x00\x00\x00\x01"], (-0x0FFFFFFFFFFFFFFFF).test_pack_2comp(2, 4, 0, BIG_ENDIAN))
assert_equal([+1, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"], (+0x0FFFFFFFFFFFFFFFF).test_pack_2comp(2, 4, 0, BIG_ENDIAN))
assert_equal([+2, "\x00\x00\x00\x00\x00\x00\x00\x00"], (+0x10000000000000000).test_pack_2comp(2, 4, 0, BIG_ENDIAN))
assert_equal([+2, "\x00\x00\x00\x00\x00\x00\x00\x01"], (+0x10000000000000001).test_pack_2comp(2, 4, 0, BIG_ENDIAN))
assert_equal([-2, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"], (-0x10000000000000001).test_pack(2, 4, 0, TWOCOMP|BIG_ENDIAN))
assert_equal([-1, "\x00\x00\x00\x00\x00\x00\x00\x00"], (-0x10000000000000000).test_pack(2, 4, 0, TWOCOMP|BIG_ENDIAN))
assert_equal([-1, "\x00\x00\x00\x00\x00\x00\x00\x01"], (-0x0FFFFFFFFFFFFFFFF).test_pack(2, 4, 0, TWOCOMP|BIG_ENDIAN))
assert_equal([+1, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"], (+0x0FFFFFFFFFFFFFFFF).test_pack(2, 4, 0, TWOCOMP|BIG_ENDIAN))
assert_equal([+2, "\x00\x00\x00\x00\x00\x00\x00\x00"], (+0x10000000000000000).test_pack(2, 4, 0, TWOCOMP|BIG_ENDIAN))
assert_equal([+2, "\x00\x00\x00\x00\x00\x00\x00\x01"], (+0x10000000000000001).test_pack(2, 4, 0, TWOCOMP|BIG_ENDIAN))
end
def test_unpack_zero