Project

General

Profile

Actions

Bug #8697

closed

Fixnum complement operator issue

Added by torimus (Torimus GL) over 11 years ago. Updated over 11 years ago.

Status:
Rejected
Assignee:
-
Target version:
ruby -v:
1.9.3p448
[ruby-core:56228]

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-40731

Author: 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

--
http://bugs.ruby-lang.org/

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
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0