Bug #8204

ObjectSpace.each_object(Bignum) can generate Bignums that are to small to be Bignums

Added by Hans Mackowiak about 1 year ago. Updated about 1 year ago.

[ruby-core:53893]
Status:Closed
Priority:Normal
Assignee:Koichi Sasada
Category:core
Target version:2.1.0
ruby -v:ruby 2.1.0dev (2013-04-02 trunk 40068) [x86_64-linux] Backport:

Description

when i do:

p ObjectSpace.eachobject(Bignum).toa
=> [18446744073709551615, 3, 2394213621560389257607583714845333205]
and again:
ObjectSpace.eachobject(Bignum).toa
=> [18446744073709551615, 3, 63326588221939058800767348888534802301, 0, 0, 0]

my question: why does the 3 and the zeros show up?

n = ObjectSpace.each_object(Bignum).min #=> 0
p n.class #Bignum
p n.zero? #=> false
p n < 0 # true

okay this means i have a zero, that looks like zero, but is not a zero and its class is Bignum

(but when i try in a new ruby session)

(2**64) < 0;
p bigZero = ObjectSpace.each_object(Bignum).min #=> 0
p bigZero.class #Bignum
p bigZero.zero? #=> true

okay, this time i get a zero that looks like a zero, and react like a zero, but its still a Bignum

so where does the zeros come from and why does they react so totaly different?

Associated revisions

Revision 40076
Added by Nobuyoshi Nakada about 1 year ago

bignum.c: Bignum zero comparison

  • bignum.c (rbbigeq): test as Fixnum if possible and get rid of zero length Bignum. [Bug #8204]

Revision 40077
Added by Nobuyoshi Nakada about 1 year ago

bignum.c: hide intermediate Bignums

  • bignum.c (rbbigeq): hide intermediate Bignums not just freeing memory. [Bug #8204]
  • object.c (rbobjhide): hide an object by clearing klass.

History

#1 Updated by Hiroshi SHIBATA about 1 year ago

  • Category set to core
  • Assignee set to Koichi Sasada
  • Target version set to 2.1.0

#2 Updated by Anonymous about 1 year ago

Note that you can obtain whichever Bignum you want using coerce. For
example:

x = (1 << 100).coerce(42).first # => 42
x.class # => Bignum

I saw that used in test/*

I never bothered to investigate it, but I'm pretty sure this could lead to
multiple bugs as MRI assumes that Bignum means big number in many places.

On Tue, Apr 2, 2013 at 9:12 PM, hsbt (Hiroshi SHIBATA) <
shibata.hiroshi@gmail.com> wrote:

Issue #8204 has been updated by hsbt (Hiroshi SHIBATA).

Category set to core
Assignee set to ko1 (Koichi Sasada)
Target version set to current: 2.1.0


Bug #8204: ObjectSpace.each_object(Bignum) can generate Bignums that are
to small to be Bignums
https://bugs.ruby-lang.org/issues/8204#change-38132

Author: Hanmac (Hans Mackowiak)
Status: Open
Priority: Normal
Assignee: ko1 (Koichi Sasada)
Category: core
Target version: current: 2.1.0
ruby -v: ruby 2.1.0dev (2013-04-02 trunk 40068) [x86_64-linux]

when i do:

p ObjectSpace.eachobject(Bignum).toa
=> [18446744073709551615, 3, 2394213621560389257607583714845333205]
and again:
ObjectSpace.eachobject(Bignum).toa
=> [18446744073709551615, 3, 63326588221939058800767348888534802301, 0, 0,
0]

my question: why does the 3 and the zeros show up?

n = ObjectSpace.each_object(Bignum).min #=> 0
p n.class #Bignum
p n.zero? #=> false
p n < 0 # true

okay this means i have a zero, that looks like zero, but is not a zero and
its class is Bignum

(but when i try in a new ruby session)

(2**64) < 0;
p bigZero = ObjectSpace.each_object(Bignum).min #=> 0
p bigZero.class #Bignum
p bigZero.zero? #=> true

okay, this time i get a zero that looks like a zero, and react like a
zero, but its still a Bignum

so where does the zeros come from and why does they react so totaly
different?

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

#3 Updated by Nobuyoshi Nakada about 1 year ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100

This issue was solved with changeset r40076.
Hans, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


bignum.c: Bignum zero comparison

  • bignum.c (rbbigeq): test as Fixnum if possible and get rid of zero length Bignum. [Bug #8204]

#4 Updated by Hans Mackowiak about 1 year ago

okay that solvs a bit, so the generated Bignums are zero too,
but for sample

ObjectSpace.each_object(Bignum).select &:zero?

still generates Bignum zeros and the 3 that was inside the Bignum list at the beginning confuses me

#5 Updated by Nobuyoshi Nakada about 1 year ago

x = (1 << 100).coerce(42).first # => 42
x.class # => Bignum

It's a Feature.

Numeric#coerce must return a pair of converted interoperable values.

In future version, Fixnum and Bignum might be merged.
However, these commits do not intend it.
Just fixes the comparison, and hides and frees intermediate objects earlier.

Also available in: Atom PDF