From: shyouhei@... Date: 2017-07-04T05:06:52+00:00 Subject: [ruby-core:81895] [Ruby trunk Bug#13711] Unexpected behavior of bit_length method on negative integers Issue #13711 has been updated by shyouhei (Shyouhei Urabe). jzakiya (Jabari Zakiya) wrote: > I would have thought that **bit_length** on a negative integer would return the number > of bits it takes to represent a two's complement number on the given cpu/os. No. This is where confusion happens. Ruby's integers theoretically have infinite widths; you can express numbers far bigger than 32 or 64 bits restrictions. Given the infinite nature of our Integers, any negative numbers theoretically have leading 111... bits forever in their 2's complement expression. If you define integer's widths as you thought, the value is always ���. ``` irb(main):004:0> printf("%.10b\n", -5) ..11111011 => nil ``` Here in this output, "..111" denotes that there are infinite 1s not shown due to printf's restriction. So to give you a meaningful return value than infinity, bit_length of negative integers are defined as they are now. ---------------------------------------- Bug #13711: Unexpected behavior of bit_length method on negative integers https://bugs.ruby-lang.org/issues/13711#change-65622 * Author: jzakiya (Jabari Zakiya) * Status: Open * Priority: Normal * Assignee: * Target version: * ruby -v: * Backport: 2.2: UNKNOWN, 2.3: UNKNOWN, 2.4: UNKNOWN ---------------------------------------- The two's complement representation of negative integers produces unexpected results when the **bit_length** method is applied to them. ``` 5.bit_length => 3 4.bit_length => 3 3.bit_length => 2 2.bit_length => 2 1.bit_length => 1 0.bit_length => 0 (-1).bit_length => 0 (-2).bit_length => 1 (-3).bit_length => 2 (-4).bit_length => 2 (-5).bit_length => 3 (-6).bit_length => 3 (-7).bit_length => 3 (-8).bit_length => 3 (-9).bit_length => 4 ``` I would have thought that **bit_length** on a negative integer would return the number of bits it takes to represent a two's complement number on the given cpu/os. Since the two's complement of negative integers are of the form: ``` -1 => 111111111111111111 -2 => 111111111111111110 -3 => 111111111111111101 -4 => 111111111111111100 -5 => 111111111111111011 -6 => 111111111111111010 -7 => 111111111111111001 -8 => 111111111111111000 -9 => 111111111111110111 ``` it thus appears for negative integers **bit_length** returns the bit position of the left most **0** of the two's complement representation. Is this correct? Is this intentional? If so, can an explanation of this behavior/rationale be given. -- https://bugs.ruby-lang.org/ Unsubscribe: