(Final) [PATCH] Subtle bug in bignum.c

[snip]

Run the following script. It should produce no output (and
occasionally this is what happens). But frequently, the
values of a and b differ.
This should not happen, but it does. I have reproduced the
problem on several different machines, running several
different flavors of linux.

10.times {
    (0x10000..0x20000).each { |i|
        a = (i*-12345) & 0xFFFFFFFF
        b = (i*-12345) & 0xFFFFFFFF
        print "#{i.to_s(2)} #{a.to_s(2)} #{b.to_s(2)}\n" if a != b
        }
    }

I _cannot_ reproduce the problem (running winxp). I have run it and even
looping it 10 times of your 10. Maybe I should loop more?

A similar problem can b shown with bitwise-or

10.times {
    (0x10000..0x20000).each { |i|
        a = (i*-12345) | 0
        b = (i*-12345) | 0
        print "#{i.to_s(2)} #{a.to_s(2)} #{{b.to_s(2)}\n" if a != b

                              small typo here ^^^^

        }
    }

But the problem does NOT occur with bitwise-xor:

10.times {
    (0x10000..0x20000).each { |i|
        a = (i*-12345) ^ 0
        b = (i*-12345) ^ 0
        print "#{i.to_s(2)} #{a.to_s(2)} #{{b.to_s(2)}\n" if a != b

                              small typo here ^^^^

        }
    }
[snip]
I used GCC 3.2.2 & 3.3.2 when compiling ruby, from otherwise
unmodified 1.8.1 sources. I looked in CVS and saw no post
1.8.1 changes that appeared relevant.

-- Markus (MQR) Roberts

kind regards -botp

···

Markus [mailto:markus@reality.com] wrote:

From what we've been able to determine (and I believe this is the

correct explanation) the problem only arises when garbage collection
occurs in the middle of the Bignum::& operation. If you have more free
memory it may take many more passes for you to see the problem.

Another possibility: what version of Ruby are you running?

The doubled "{{" typo is very odd. It was a single "{" in the original,
but you are correct, the "{" is doubled in the mail as received.

-- Markus

···

On Tue, 2004-08-31 at 19:49, "Peña, Botp" wrote:

Markus [mailto:markus@reality.com] wrote:
[snip]
> Run the following script. It should produce no output (and
> occasionally this is what happens). But frequently, the
> values of a and b differ.
> This should not happen, but it does. I have reproduced the
> problem on several different machines, running several
> different flavors of linux.
>
> 10.times {
> (0x10000..0x20000).each { |i|
> a = (i*-12345) & 0xFFFFFFFF
> b = (i*-12345) & 0xFFFFFFFF
> print "#{i.to_s(2)} #{a.to_s(2)} #{b.to_s(2)}\n" if a != b
> }
> }

I _cannot_ reproduce the problem (running winxp). I have run it and even
looping it 10 times of your 10. Maybe I should loop more?

>
> A similar problem can b shown with bitwise-or
>
>
> 10.times {
> (0x10000..0x20000).each { |i|
> a = (i*-12345) | 0
> b = (i*-12345) | 0
> print "#{i.to_s(2)} #{a.to_s(2)} #{{b.to_s(2)}\n" if a != b

                              small typo here ^^^^

> }
> }
>
>
> But the problem does NOT occur with bitwise-xor:
>
> 10.times {
> (0x10000..0x20000).each { |i|
> a = (i*-12345) ^ 0
> b = (i*-12345) ^ 0
> print "#{i.to_s(2)} #{a.to_s(2)} #{{b.to_s(2)}\n" if a != b

                              small typo here ^^^^

> }
> }
> [snip]
> I used GCC 3.2.2 & 3.3.2 when compiling ruby, from otherwise
> unmodified 1.8.1 sources. I looked in CVS and saw no post
> 1.8.1 changes that appeared relevant.
>
> -- Markus (MQR) Roberts
>

kind regards -botp