Feature #8553
closedBignum#size (and Fixnum#size)
Description
How about changing Bignum#size to a well defined behavior?
Recently I changed Bignum implementation to use 128 bit integer type
if the type is available. (r41379)
After that, rubyspec fails with Bignum#size as follows:
| 1)
| Bignum#size returns the number of bytes in the machine representation in multiples of four FAILED
| Expected 16
| to equal 12
|
http://a.mrkn.jp/~mrkn/chkbuild/mavericks/ruby-trunk-m64-o3/log/20130620T231101Z.log.html.gz
I think this failure itself is not a problem.
This is just an over-specification of rubyspec.
Actually the test also fails before r41379 on platforms which doesn't support 64 bit integer type.
It is because the Bignum#size returns multiples of sizeof(BDIGIT), not 4.
sizeof(BDIGIT) can be 2 or 4 before r41379 or 8 since r41379.
The test only considers platforms sizeof(BDIGIT) is 4.
However this test failure reminds me that I always felt that current
Bignum#size (and Fixnum#size) behavior is not useful.
I guess almost all people doesn't interest sizeof(BDIGIT).
So I'd like to change Bignum#size to return number of bytes.
It means val.size returns n if val is a Bignum and
256n <= abs(val) < 256(n+1).
One exception is that val.size returns 0 if val is Bignum zero.
My considerations:
-
The above Bignum#size behavior is based on absolute values, abs(n).
This is compatible to current behavior and easy to understand.
There are other possibilities: exception on negative values and
definition on 2's complement value.
I think exception is too different from current behavior.
A definition based on 2's complement is difficult to treat sign bits. -
Bignum#size returns number of bytes, not bits.
I think some method which returns number of bits may be useful but
it is different from current Bignum#size.
It is better to name another one, such as bitsize and it is not this issue. -
Fixnum#size is difficult to change.
Currently Fixnum#size returns sizeof(long).
Some programs, mspec for example, uses it to obtain a word size.
So it is difficult to change because compatibility.
However I doubt such use is correct.
If a program want to detect 64bit platform, Fixnum#size should not be used
because it returns 4 on LLP64 platforms (64bit Windows).
It is better to use [0].pack("l!").size for sizof(long) and
[nil].pack("p").size for sizeof(char *).However some people may hope Fixnum and Bignum consistent.
For that purpose, Fixnum#size should also be changed same way.
It will breaks some applications, though.
Any opinion?
Files