mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* include/ruby/intern.h (rb_absint_size): Declaration moved from
internal.h to calculate required buffer size to pack integers. (rb_absint_numwords): Ditto. (rb_absint_singlebit_p): Ditto. [ruby-core:42813] [Feature #6065] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42208 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
56150eba92
commit
e5ff9d58ef
6 changed files with 111 additions and 3 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
Sun Jul 28 11:12:07 2013 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
|
* include/ruby/intern.h (rb_absint_size): Declaration moved from
|
||||||
|
internal.h to calculate required buffer size to pack integers.
|
||||||
|
(rb_absint_numwords): Ditto.
|
||||||
|
(rb_absint_singlebit_p): Ditto.
|
||||||
|
[ruby-core:42813] [Feature #6065]
|
||||||
|
|
||||||
Sun Jul 28 10:54:26 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Sun Jul 28 10:54:26 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* win32/win32.c (rb_w32_pipe): fix pipe name formatting. as "%x" may
|
* win32/win32.c (rb_w32_pipe): fix pipe name formatting. as "%x" may
|
||||||
|
|
28
bignum.c
28
bignum.c
|
@ -3275,6 +3275,34 @@ rb_absint_numwords(VALUE val, size_t word_numbits, size_t *nlz_bits_ret)
|
||||||
return numwords;
|
return numwords;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Test abs(val) consists only a bit or not.
|
||||||
|
*
|
||||||
|
* Returns 1 if abs(val) == 1 << n for some n >= 0.
|
||||||
|
* Returns 0 otherwise.
|
||||||
|
*
|
||||||
|
* rb_absint_singlebit_p can be used to determine required buffer size
|
||||||
|
* for rb_integer_pack used with INTEGER_PACK_2COMP (two's complement).
|
||||||
|
*
|
||||||
|
* Following example calculates number of bits required to
|
||||||
|
* represent val in two's complement number, without sign bit.
|
||||||
|
*
|
||||||
|
* size_t size;
|
||||||
|
* int neg = FIXNUM_P(val) ? FIX2LONG(val) < 0 : RBIGNUM_NEGATIVE_P(val);
|
||||||
|
* size = rb_absint_numwords(val, 1, NULL)
|
||||||
|
* if (size == (size_t)-1) ...overflow...
|
||||||
|
* if (neg && rb_absint_singlebit_p(val))
|
||||||
|
* size--;
|
||||||
|
*
|
||||||
|
* Following example calculates number of bytes required to
|
||||||
|
* represent val in two's complement number, with sign bit.
|
||||||
|
*
|
||||||
|
* size_t size;
|
||||||
|
* int neg = FIXNUM_P(val) ? FIX2LONG(val) < 0 : RBIGNUM_NEGATIVE_P(val);
|
||||||
|
* int nlz_bits;
|
||||||
|
* size = rb_absint_size(val, &nlz_bits);
|
||||||
|
* if (nlz_bits == 0 && !(neg && rb_absint_singlebit_p(val)))
|
||||||
|
* size++;
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
rb_absint_singlebit_p(VALUE val)
|
rb_absint_singlebit_p(VALUE val)
|
||||||
{
|
{
|
||||||
|
|
|
@ -45,6 +45,26 @@ rb_integer_unpack_m(VALUE klass, VALUE buf, VALUE numwords, VALUE wordsize, VALU
|
||||||
NUM2SIZET(nails), NUM2INT(flags));
|
NUM2SIZET(nails), NUM2INT(flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
rb_integer_test_numbits_2comp_without_sign(VALUE val)
|
||||||
|
{
|
||||||
|
size_t size;
|
||||||
|
int neg = FIXNUM_P(val) ? FIX2LONG(val) < 0 : RBIGNUM_NEGATIVE_P(val);
|
||||||
|
size = rb_absint_numwords(val, 1, NULL) - (neg && rb_absint_singlebit_p(val));
|
||||||
|
return SIZET2NUM(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
rb_integer_test_numbytes_2comp_with_sign(VALUE val)
|
||||||
|
{
|
||||||
|
int neg = FIXNUM_P(val) ? FIX2LONG(val) < 0 : RBIGNUM_NEGATIVE_P(val);
|
||||||
|
int nlz_bits;
|
||||||
|
size_t size = rb_absint_size(val, &nlz_bits);
|
||||||
|
if (nlz_bits == 0 && !(neg && rb_absint_singlebit_p(val)))
|
||||||
|
size++;
|
||||||
|
return SIZET2NUM(size);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Init_intpack(VALUE klass)
|
Init_intpack(VALUE klass)
|
||||||
{
|
{
|
||||||
|
@ -62,4 +82,7 @@ Init_intpack(VALUE klass)
|
||||||
rb_define_const(rb_cInteger, "INTEGER_PACK_FORCE_BIGNUM", INT2NUM(INTEGER_PACK_FORCE_BIGNUM));
|
rb_define_const(rb_cInteger, "INTEGER_PACK_FORCE_BIGNUM", INT2NUM(INTEGER_PACK_FORCE_BIGNUM));
|
||||||
rb_define_const(rb_cInteger, "INTEGER_PACK_NEGATIVE", INT2NUM(INTEGER_PACK_NEGATIVE));
|
rb_define_const(rb_cInteger, "INTEGER_PACK_NEGATIVE", INT2NUM(INTEGER_PACK_NEGATIVE));
|
||||||
rb_define_const(rb_cInteger, "INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION", INT2NUM(INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION));
|
rb_define_const(rb_cInteger, "INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION", INT2NUM(INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION));
|
||||||
|
|
||||||
|
rb_define_method(rb_cInteger, "test_numbits_2comp_without_sign", rb_integer_test_numbits_2comp_without_sign, 0);
|
||||||
|
rb_define_method(rb_cInteger, "test_numbytes_2comp_with_sign", rb_integer_test_numbytes_2comp_with_sign, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,6 +157,9 @@ VALUE rb_big_rshift(VALUE, VALUE);
|
||||||
INTEGER_PACK_MSBYTE_FIRST)
|
INTEGER_PACK_MSBYTE_FIRST)
|
||||||
int rb_integer_pack(VALUE val, void *words, size_t numwords, size_t wordsize, size_t nails, int flags);
|
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(const void *words, size_t numwords, size_t wordsize, size_t nails, int flags);
|
||||||
|
size_t rb_absint_size(VALUE val, int *nlz_bits_ret);
|
||||||
|
size_t rb_absint_numwords(VALUE val, size_t word_numbits, size_t *nlz_bits_ret);
|
||||||
|
int rb_absint_singlebit_p(VALUE val);
|
||||||
|
|
||||||
/* rational.c */
|
/* rational.c */
|
||||||
VALUE rb_rational_raw(VALUE, VALUE);
|
VALUE rb_rational_raw(VALUE, VALUE);
|
||||||
|
|
|
@ -141,9 +141,6 @@ VALUE rb_big_fdiv(VALUE x, VALUE y);
|
||||||
VALUE rb_big_uminus(VALUE x);
|
VALUE rb_big_uminus(VALUE x);
|
||||||
VALUE rb_integer_float_cmp(VALUE x, VALUE y);
|
VALUE rb_integer_float_cmp(VALUE x, VALUE y);
|
||||||
VALUE rb_integer_float_eq(VALUE x, VALUE y);
|
VALUE rb_integer_float_eq(VALUE x, VALUE y);
|
||||||
size_t rb_absint_size(VALUE val, int *nlz_bits_ret);
|
|
||||||
size_t rb_absint_numwords(VALUE val, size_t word_numbits, size_t *nlz_bits_ret);
|
|
||||||
int rb_absint_singlebit_p(VALUE val);
|
|
||||||
|
|
||||||
/* class.c */
|
/* class.c */
|
||||||
VALUE rb_obj_methods(int argc, VALUE *argv, VALUE obj);
|
VALUE rb_obj_methods(int argc, VALUE *argv, VALUE obj);
|
||||||
|
|
|
@ -322,4 +322,53 @@ class TestBignum < Test::Unit::TestCase
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_numbits_2comp
|
||||||
|
assert_equal(4, -9.test_numbits_2comp_without_sign)
|
||||||
|
assert_equal(3, -8.test_numbits_2comp_without_sign)
|
||||||
|
assert_equal(3, -7.test_numbits_2comp_without_sign)
|
||||||
|
assert_equal(3, -6.test_numbits_2comp_without_sign)
|
||||||
|
assert_equal(3, -5.test_numbits_2comp_without_sign)
|
||||||
|
assert_equal(2, -4.test_numbits_2comp_without_sign)
|
||||||
|
assert_equal(2, -3.test_numbits_2comp_without_sign)
|
||||||
|
assert_equal(1, -2.test_numbits_2comp_without_sign)
|
||||||
|
assert_equal(0, -1.test_numbits_2comp_without_sign)
|
||||||
|
assert_equal(0, 0.test_numbits_2comp_without_sign)
|
||||||
|
assert_equal(1, 1.test_numbits_2comp_without_sign)
|
||||||
|
assert_equal(2, 2.test_numbits_2comp_without_sign)
|
||||||
|
assert_equal(2, 3.test_numbits_2comp_without_sign)
|
||||||
|
assert_equal(3, 4.test_numbits_2comp_without_sign)
|
||||||
|
assert_equal(3, 5.test_numbits_2comp_without_sign)
|
||||||
|
assert_equal(3, 6.test_numbits_2comp_without_sign)
|
||||||
|
assert_equal(3, 7.test_numbits_2comp_without_sign)
|
||||||
|
assert_equal(4, 8.test_numbits_2comp_without_sign)
|
||||||
|
assert_equal(4, 9.test_numbits_2comp_without_sign)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_numbytes_2comp
|
||||||
|
assert_equal(6, -0x8000000001.test_numbytes_2comp_with_sign)
|
||||||
|
assert_equal(5, -0x8000000000.test_numbytes_2comp_with_sign)
|
||||||
|
assert_equal(5, -0x80000001.test_numbytes_2comp_with_sign)
|
||||||
|
assert_equal(4, -0x80000000.test_numbytes_2comp_with_sign)
|
||||||
|
assert_equal(4, -0x800001.test_numbytes_2comp_with_sign)
|
||||||
|
assert_equal(3, -0x800000.test_numbytes_2comp_with_sign)
|
||||||
|
assert_equal(3, -0x8001.test_numbytes_2comp_with_sign)
|
||||||
|
assert_equal(2, -0x8000.test_numbytes_2comp_with_sign)
|
||||||
|
assert_equal(2, -0x81.test_numbytes_2comp_with_sign)
|
||||||
|
assert_equal(1, -0x80.test_numbytes_2comp_with_sign)
|
||||||
|
assert_equal(1, -1.test_numbytes_2comp_with_sign)
|
||||||
|
assert_equal(1, 0.test_numbytes_2comp_with_sign)
|
||||||
|
assert_equal(1, 1.test_numbytes_2comp_with_sign)
|
||||||
|
assert_equal(1, 0x7f.test_numbytes_2comp_with_sign)
|
||||||
|
assert_equal(2, 0x80.test_numbytes_2comp_with_sign)
|
||||||
|
assert_equal(2, 0x7fff.test_numbytes_2comp_with_sign)
|
||||||
|
assert_equal(3, 0x8000.test_numbytes_2comp_with_sign)
|
||||||
|
assert_equal(3, 0x7fffff.test_numbytes_2comp_with_sign)
|
||||||
|
assert_equal(4, 0x800000.test_numbytes_2comp_with_sign)
|
||||||
|
assert_equal(4, 0x7fffffff.test_numbytes_2comp_with_sign)
|
||||||
|
assert_equal(5, 0x80000000.test_numbytes_2comp_with_sign)
|
||||||
|
assert_equal(5, 0x7fffffffff.test_numbytes_2comp_with_sign)
|
||||||
|
assert_equal(6, 0x8000000000.test_numbytes_2comp_with_sign)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue