Bug #8697
closedFixnum complement operator issue
Description
=begin
By the ((<documentation|URL:http://www.ruby-doc.org/core-2.0/Fixnum.html#method-i-7E>)), bitwise complement operator ((~)) to Fixnum instance should do ((one's complement)) with just flipping all bits. In fact, current implementation does ((two's complement)) due to or-ing with FIXNUM_FLAG, which is defined as 1.
Either fix the documentation or the fix_rev function implementation.
Affected versions: both 1.9.3 and 2.0.0
=end
Updated by akr (Akira Tanaka) over 11 years ago
- Status changed from Open to Feedback
Please show us an actual problem.
At least, ~0 is -1 as follows.
% ./ruby -v -e 'p ~0'
ruby 2.1.0dev (2013-07-26 trunk 42199) [x86_64-linux]
-1
-1 is the number which all bits are one.
0 is the number which all bits are zero.
So, -1 is the one's complement of 0 as documented.
Updated by torimus (Torimus GL) over 11 years ago
=begin
When one's complement is applied to zero, the result is ((not)) -1 but so called "negative zero", ie. -0.
What you are talking about is two's complement, ie. "the value of 1 is then added to the resulting value of bitwise not operation".
It's all about improper use of terminology.
See related articles on Wikipedia: ((<One's complement|URL:http://en.wikipedia.org/wiki/Ones%27_complement>)) and ((<Two's complement|URL:http://en.wikipedia.org/wiki/Two%27s_complement>)) .
=end
Updated by mame (Yusuke Endoh) over 11 years ago
=begin
I guess you mistake "the ones' complement of a binary number" for "the ones' complement system".
The former is a kind of operation for the binary representation of a number, no matter what the number itself is.
The latter gives a mapping that corresponds the binary representations to mathematical numbers.
See related articles on Wikipedia: ((<One's complement|URL:http://en.wikipedia.org/wiki/Ones%27_complement>))
Actually it says:
The ones' complement of a binary number is defined as the value obtained by inverting all the bits in the binary representation of the number
For example, the bit pattern of +0 is "all 0s" in both ones' and twos' complement systems.
By the definition above, applying the ones' complement to +0 yields a number whose binary representation is "all 1s".
This number that has "all 1" bit pattern represents -0 in ones' complement system, and -1 in twos' complement system.
Ruby's Integer uses twos' complement system.
Even without knowledge of it, "the ones' complement of 0 is -1", is very common phrase in the computer science. There is nothing wrong in both the implementation and documentation of Fixnum#~.
=end
Updated by torimus (Torimus GL) over 11 years ago
=begin
As you've admitted, ~ operator implementation does more than ((just flipping of it's each bit)). It also does an additional step when converting to two's complement by doing bitwise or with number 1 ((({return ~num | FIXNUM_FLAG}))). As the rest of bit operators also counts in two's complement and also #to_s method is aware of it, this fact is then shadowed. If Ruby wouldn't automatically convert to BigDecimal when the register size is exceed, this would show off when the highest bit 'overflows'.
I can understand why Ruby does this conversions internally but I see no reason for vague descriptions in the documentation and hiding this fact. Why current text to FixNum's ~ simply doesn't speak about two's complement directly ?
=end
Updated by david_macmahon (David MacMahon) over 11 years ago
The bit inverted VALUE is OR'd with FIXNUM_FLAG so that Ruby will still recognize the VALUE as a Fixnum. It is NOT done to convert to two's complement (which would actually require adding 1 to the bit inverted value rather).
You can see that the OR with FIXNUM_FLAG does not show up in the result by looking at the binary representation of any bit inverted odd number (e.g. ~1):
$ ruby -e 'puts "%b" % ~1'
..10
Dave
On Jul 28, 2013, at 1:39 AM, torimus (Torimus GL) wrote:
Issue #8697 has been updated by torimus (Torimus GL).
=begin
As you've admitted, ~ operator implementation does more than ((just flipping of it's each bit)). It also does an additional step when converting to two's complement by doing bitwise or with number 1 ((({return ~num | FIXNUM_FLAG}))). As the rest of bit operators also counts in two's complement and also #to_s method is aware of it, this fact is then shadowed. If Ruby wouldn't automatically convert to BigDecimal when the register size is exceed, this would show off when the highest bit 'overflows'.I can understand why Ruby does this conversions internally but I see no reason for vague descriptions in the documentation and hiding this fact. Why current text to FixNum's ~ simply doesn't speak about two's complement directly ?
=end
Bug #8697: Fixnum complement operator issue
https://bugs.ruby-lang.org/issues/8697#change-40731Author: torimus (Torimus GL)
Status: Feedback
Priority: Normal
Assignee:
Category: core
Target version: current: 2.1.0
ruby -v: 1.9.3p448
Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN=begin
By the ((<documentation|URL:http://www.ruby-doc.org/core-2.0/Fixnum.html#method-i-7E>)), bitwise complement operator ((~)) to Fixnum instance should do ((one's complement)) with just flipping all bits. In fact, current implementation does ((two's complement)) due to or-ing with FIXNUM_FLAG, which is defined as 1.Either fix the documentation or the fix_rev function implementation.
Affected versions: both 1.9.3 and 2.0.0
=end
Updated by phluid61 (Matthew Kerwin) over 11 years ago
Can we close this issue? The original report confuses MRI implementation details (storing of small integers in Fixnum VALUEs) with language-level operations, which I believe has been explained sufficiently. This is a non-issue.
Updated by Anonymous over 11 years ago
- Status changed from Feedback to Rejected