ruby-changes:29145
From: akr <ko1@a...>
Date: Sun, 9 Jun 2013 21:37:53 +0900 (JST)
Subject: [ruby-changes:29145] akr:r41197 (trunk): * bignum.c (rb_absint_numwords): Return (size_t)-1 when overflow.
akr 2013-06-09 21:37:38 +0900 (Sun, 09 Jun 2013) New Revision: 41197 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=41197 Log: * bignum.c (rb_absint_numwords): Return (size_t)-1 when overflow. Refine variable names. (rb_absint_size): Refine variable names. * internal.h (rb_absint_size): Refine an argument name. (rb_absint_numwords): Ditto. Modified files: trunk/ChangeLog trunk/bignum.c trunk/internal.h Index: ChangeLog =================================================================== --- ChangeLog (revision 41196) +++ ChangeLog (revision 41197) @@ -1,3 +1,12 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Sun Jun 9 21:33:15 2013 Tanaka Akira <akr@f...> + + * bignum.c (rb_absint_numwords): Return (size_t)-1 when overflow. + Refine variable names. + (rb_absint_size): Refine variable names. + + * internal.h (rb_absint_size): Refine an argument name. + (rb_absint_numwords): Ditto. + Sun Jun 9 16:51:41 2013 Tanaka Akira <akr@f...> * bignum.c (rb_absint_numwords): Renamed from rb_absint_size_in_word. Index: internal.h =================================================================== --- internal.h (revision 41196) +++ internal.h (revision 41197) @@ -119,8 +119,8 @@ VALUE rb_big_fdiv(VALUE x, VALUE y); https://github.com/ruby/ruby/blob/trunk/internal.h#L119 VALUE rb_big_uminus(VALUE x); VALUE rb_integer_float_cmp(VALUE x, VALUE y); VALUE rb_integer_float_eq(VALUE x, VALUE y); -size_t rb_absint_size(VALUE val, int *number_of_leading_zero_bits); -size_t rb_absint_numwords(VALUE val, size_t word_numbits, size_t *number_of_leading_zero_bits); +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 */ Index: bignum.c =================================================================== --- bignum.c (revision 41196) +++ bignum.c (revision 41197) @@ -452,8 +452,25 @@ rb_big_unpack(unsigned long *buf, long n https://github.com/ruby/ruby/blob/trunk/bignum.c#L452 } /* number of bytes of abs(val). additionaly number of leading zeros can be returned. */ + +/* + * Calculate a number of bytes to be required to represent + * the absolute value of the integer given as _val_. + * + * [val] an integer. + * [nlz_bits_ret] number of leading zero bits in the most significant byte is returned if not NULL. + * + * This function returns ((val_numbits * CHAR_BIT + CHAR_BIT - 1) / CHAR_BIT) + * where val_numbits is the number of bits of abs(val). + * This function should not overflow. + * + * If nlz_bits_ret is not NULL, + * (return_value * CHAR_BIT - val_numbits) is stored in *nlz_bits_ret. + * In this case, 0 <= *nlz_bits_ret < CHAR_BIT. + * + */ size_t -rb_absint_size(VALUE val, int *number_of_leading_zero_bits) +rb_absint_size(VALUE val, int *nlz_bits_ret) { BDIGIT *dp; BDIGIT *de; @@ -489,51 +506,76 @@ rb_absint_size(VALUE val, int *number_of https://github.com/ruby/ruby/blob/trunk/bignum.c#L506 while (dp < de && de[-1] == 0) de--; if (dp == de) { - if (number_of_leading_zero_bits) - *number_of_leading_zero_bits = 0; + if (nlz_bits_ret) + *nlz_bits_ret = 0; return 0; } num_leading_zeros = nlz(de[-1]); - if (number_of_leading_zero_bits) - *number_of_leading_zero_bits = num_leading_zeros % CHAR_BIT; + if (nlz_bits_ret) + *nlz_bits_ret = num_leading_zeros % CHAR_BIT; return (de - dp) * SIZEOF_BDIGITS - num_leading_zeros / CHAR_BIT; } +/* + * Calculate a number of words to be required to represent + * the absolute value of the integer given as _val_. + * + * [val] an integer. + * [word_numbits] number of bits in a word. + * [nlz_bits_ret] number of leading zero bits in the most significant word is returned if not NULL. + * + * This function returns ((val_numbits * CHAR_BIT + word_numbits - 1) / word_numbits) + * where val_numbits is the number of bits of abs(val). + * If it overflows, (size_t)-1 is returned. + * + * If nlz_bits_ret is not NULL and overflow is not occur, + * (return_value * word_numbits - val_numbits) is stored in *nlz_bits_ret. + * In this case, 0 <= *nlz_bits_ret < word_numbits. + * + */ size_t -rb_absint_numwords(VALUE val, size_t word_numbits_arg, size_t *number_of_leading_zero_bits) +rb_absint_numwords(VALUE val, size_t word_numbits, size_t *nlz_bits_ret) { size_t numbytes; size_t numwords; - int zerobits_in_byte; - VALUE val_numbits, word_numbits; + size_t nlz_bits; + int nlz_bits_in_msbyte; + VALUE val_numbits, word_numbits_v; VALUE div_mod, div, mod; + int sign; + + if (word_numbits == 0) + return (size_t)-1; - numbytes = rb_absint_size(val, &zerobits_in_byte); + numbytes = rb_absint_size(val, &nlz_bits_in_msbyte); /* - * val_numbits = numbytes * CHAR_BIT - zerobits_in_byte + * val_numbits = numbytes * CHAR_BIT - nlz_bits_in_msbyte * div, mod = val_numbits.divmod(word_numbits) * numwords = mod == 0 ? div : div + 1 - * number_of_leading_zero_bits_in_word = mod == 0 ? 0 : word_numbits - mod + * nlz_bits = mod == 0 ? 0 : word_numbits - mod */ val_numbits = SIZET2NUM(numbytes); val_numbits = rb_funcall(val_numbits, '*', 1, LONG2FIX(CHAR_BIT)); - if (zerobits_in_byte) - val_numbits = rb_funcall(val_numbits, '-', 1, LONG2FIX(zerobits_in_byte)); - word_numbits = SIZET2NUM(word_numbits_arg); - div_mod = rb_funcall(val_numbits, rb_intern("divmod"), 1, word_numbits); + if (nlz_bits_in_msbyte) + val_numbits = rb_funcall(val_numbits, '-', 1, LONG2FIX(nlz_bits_in_msbyte)); + word_numbits_v = SIZET2NUM(word_numbits); + div_mod = rb_funcall(val_numbits, rb_intern("divmod"), 1, word_numbits_v); div = RARRAY_AREF(div_mod, 0); mod = RARRAY_AREF(div_mod, 1); if (mod == LONG2FIX(0)) { - numwords = NUM2SIZET(div); - if (number_of_leading_zero_bits) - *number_of_leading_zero_bits = 0; + nlz_bits = 0; } else { - numwords = NUM2SIZET(rb_funcall(div, '+', 1, LONG2FIX(1))); - if (number_of_leading_zero_bits) - *number_of_leading_zero_bits = word_numbits_arg - NUM2SIZET(mod); + div = rb_funcall(div, '+', 1, LONG2FIX(1)); + nlz_bits = word_numbits - NUM2SIZET(mod); } + rb_integer_pack(div, &sign, &numwords, 1, sizeof(numwords), 0, + INTEGER_PACK_MSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER); + if (sign == 2) + return (size_t)-1; + if (nlz_bits_ret) + *nlz_bits_ret = nlz_bits; return numwords; } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/