[BUG] in digit logic

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|

[BUG] in digit logic

Nicolas Cellier
Hi guys,
Try this code and tell me what you think:

(1 to: 80) reject: [:n |
   ((2 raisedTo: n) negated bitAnd: (2 raisedTo: n) negated - 1)
   = (2 raisedTo: n + 1) negated].

Answer is at http://bugs.squeak.org/view.php?id=6874
I'm a bit surprised to encounter this one in VW7.7...
But hey, it must be a very old bug !

Nicolas

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [BUG] in digit logic

Nicolas Cellier
nicolas cellier <nicolas.cellier.aka.nice <at> gmail.com> writes:

>
> Hi guys,
> Try this code and tell me what you think:
>
> (1 to: 80) reject: [:n |
>    ((2 raisedTo: n) negated bitAnd: (2 raisedTo: n) negated - 1)
>    = (2 raisedTo: n + 1) negated].
>
> Answer is at http://bugs.squeak.org/view.php?id=6874
> I'm a bit surprised to encounter this one in VW7.7...
> But hey, it must be a very old bug !
>
> Nicolas
>


By the way, this bug is also written in VM stone at primitive 34.
So that makes at least to methods to be changed for a temporary workaround.

Nicolas

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [BUG] in digit logic

Andres Valloud-6
In reply to this post by Nicolas Cellier
I am not sure what to think about it.  Try this C code:

#include <stdio.h>

int main() {

    printf("%lx & %lx is %lx.\n", -(1L << 31), -(1L << 31) - 1, -(1L <<
31) & (-(1L << 31) - 1));
    printf("%i & %i is %i.\n", -(1 << 31), -(1 << 31) - 1, -(1 << 31) &
(-(1 << 31) - 1));
    return;
}


The first line does your calculation with 64 bit signed ints and outputs
the result in hex (the compiler is on a 64 bit platform).  The second
line does your calculations with 32 bit signed ints, and outputs the
results in decimal.  The resulting program produces the following:

ffffffff80000000 & ffffffff7fffffff is ffffffff00000000.
-2147483648 & 2147483647 is 0.

Smalltalk matches the second line with 32 bit integers.  Now, your
example involves large negative integers 4 bytes long.  Note that large
negative integers are stored as large integers plus a sign bit.  This
implies large negative integers in Smalltalk are meant to be just as
large as necessary.  Otherwise, they would have to be infinitely large
because there is no limit to the size of a large negative integer.  In
other words, all the "leading Fs" are removed because large negative
integers do not have a fixed size.  In the C program above, using 64 bit
ints resulted in 8 leading Fs.  How many leading Fs should negative
large integers assume?  Are you still thinking this is a bug?

Andres.

-----Original Message-----
From: [hidden email] [mailto:[hidden email]] On
Behalf Of nicolas cellier
Sent: Wednesday, April 14, 2010 12:48 PM
To: [hidden email]
Subject: [vwnc] [BUG] in digit logic

Hi guys,
Try this code and tell me what you think:

(1 to: 80) reject: [:n |
   ((2 raisedTo: n) negated bitAnd: (2 raisedTo: n) negated - 1)
   = (2 raisedTo: n + 1) negated].

Answer is at http://bugs.squeak.org/view.php?id=6874
I'm a bit surprised to encounter this one in VW7.7...
But hey, it must be a very old bug !

Nicolas

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [BUG] in digit logic

Eliot Miranda-2


On Wed, Apr 14, 2010 at 5:33 PM, Valloud, Andres <[hidden email]> wrote:
I am not sure what to think about it.  Try this C code:

#include <stdio.h>

int main() {

   printf("%lx & %lx is %lx.\n", -(1L << 31), -(1L << 31) - 1, -(1L <<
31) & (-(1L << 31) - 1));
   printf("%i & %i is %i.\n", -(1 << 31), -(1 << 31) - 1, -(1 << 31) &
(-(1 << 31) - 1));
   return;
}


The first line does your calculation with 64 bit signed ints and outputs
the result in hex (the compiler is on a 64 bit platform).  The second
line does your calculations with 32 bit signed ints, and outputs the
results in decimal.  The resulting program produces the following:

ffffffff80000000 & ffffffff7fffffff is ffffffff00000000.
-2147483648 & 2147483647 is 0.

Smalltalk matches the second line with 32 bit integers.  Now, your
example involves large negative integers 4 bytes long.  Note that large
negative integers are stored as large integers plus a sign bit.  This
implies large negative integers in Smalltalk are meant to be just as
large as necessary.  Otherwise, they would have to be infinitely large
because there is no limit to the size of a large negative integer.  In
other words, all the "leading Fs" are removed because large negative
integers do not have a fixed size.  In the C program above, using 64 bit
ints resulted in 8 leading Fs.  How many leading Fs should negative
large integers assume?  Are you still thinking this is a bug?

-1 is an infinite string of 1's (*).  Hence (-1 bitAnd: anyInteger) = anyInteger.
 
Hence negative something bitAnd: negative some other thing is negative something else.  The issue is only how many bytes negative something else requires and whether this fits in a SmallInteger or a LargeNegativeInteger of suitable size.

(*) note that the infinite string of 1's has a compact representation, namely SmallInteger -1.  But that does /not/ imply that (-1 bitAt: i) = 0 for i > 0 ever.

HTH
Eliot


Andres.

-----Original Message-----
From: [hidden email] [mailto:[hidden email]] On
Behalf Of nicolas cellier
Sent: Wednesday, April 14, 2010 12:48 PM
To: [hidden email]
Subject: [vwnc] [BUG] in digit logic

Hi guys,
Try this code and tell me what you think:

(1 to: 80) reject: [:n |
  ((2 raisedTo: n) negated bitAnd: (2 raisedTo: n) negated - 1)
  = (2 raisedTo: n + 1) negated].

Answer is at http://bugs.squeak.org/view.php?id=6874
I'm a bit surprised to encounter this one in VW7.7...
But hey, it must be a very old bug !

Nicolas

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc


_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [BUG] in digit logic

Eliot Miranda-2


On Wed, Apr 14, 2010 at 6:12 PM, Eliot Miranda <[hidden email]> wrote:


On Wed, Apr 14, 2010 at 5:33 PM, Valloud, Andres <[hidden email]> wrote:
I am not sure what to think about it.  Try this C code:

#include <stdio.h>

int main() {

   printf("%lx & %lx is %lx.\n", -(1L << 31), -(1L << 31) - 1, -(1L <<
31) & (-(1L << 31) - 1));
   printf("%i & %i is %i.\n", -(1 << 31), -(1 << 31) - 1, -(1 << 31) &
(-(1 << 31) - 1));
   return;
}


The first line does your calculation with 64 bit signed ints and outputs
the result in hex (the compiler is on a 64 bit platform).  The second
line does your calculations with 32 bit signed ints, and outputs the
results in decimal.  The resulting program produces the following:

ffffffff80000000 & ffffffff7fffffff is ffffffff00000000.
-2147483648 & 2147483647 is 0.

Smalltalk matches the second line with 32 bit integers.  Now, your
example involves large negative integers 4 bytes long.  Note that large
negative integers are stored as large integers plus a sign bit.  This
implies large negative integers in Smalltalk are meant to be just as
large as necessary.  Otherwise, they would have to be infinitely large
because there is no limit to the size of a large negative integer.  In
other words, all the "leading Fs" are removed because large negative
integers do not have a fixed size.  In the C program above, using 64 bit
ints resulted in 8 leading Fs.  How many leading Fs should negative
large integers assume?  Are you still thinking this is a bug?

-1 is an infinite string of 1's (*).  Hence (-1 bitAnd: anyInteger) = anyInteger.
 
Hence negative something bitAnd: negative some other thing is negative something else.  The issue is only how many bytes negative something else requires and whether this fits in a SmallInteger or a LargeNegativeInteger of suitable size.

(*) note that the infinite string of 1's has a compact representation, namely SmallInteger -1.  But that does /not/ imply that (-1 bitAt: i) = 0 for i > 0 ever.

HTH
Eliot

and since C doesn't implement infinite precision arithmetic, whatever C has to say on the matter is deeply suspect when not outright wrong.
 
best
Eliot

P.S.  I will not hit Send before I have read and understood my post, and verified it is complete.
         I will not hit Send before I have read and understood my post, and verified it is complete.
         I will not hit Send before I have read and understood my post, and verified it is complete.
         I will not hit Send before I have read and understood my post, and verified it is complete.
...
(to the opening music of The Simpsons)



Andres.

-----Original Message-----
From: [hidden email] [mailto:[hidden email]] On
Behalf Of nicolas cellier
Sent: Wednesday, April 14, 2010 12:48 PM
To: [hidden email]
Subject: [vwnc] [BUG] in digit logic

Hi guys,
Try this code and tell me what you think:

(1 to: 80) reject: [:n |
  ((2 raisedTo: n) negated bitAnd: (2 raisedTo: n) negated - 1)
  = (2 raisedTo: n + 1) negated].

Answer is at http://bugs.squeak.org/view.php?id=6874
I'm a bit surprised to encounter this one in VW7.7...
But hey, it must be a very old bug !

Nicolas

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc



_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [BUG] in digit logic

Andres Valloud-6
> and since C doesn't implement infinite precision arithmetic, whatever C has to say on the matter is deeply suspect when not outright wrong.
 
I think it's illustrative to see what happens with 64 bit integers as opposed to 32 bit integers.  So, as you say, if you consider the infinite precision large negative integers, and then see them as an extreme case of increasing the integer size in C, you'd be forced into an endless tail of leading 0xF nibbles.  So we don't do it, and then bitAnd: behaves "strange".
 
Also, note that Nicolas' test case was not something bitAnd: -1 exactly, hence the C test program.
 
Andres.

From: Eliot Miranda [mailto:[hidden email]]
Sent: Wednesday, April 14, 2010 6:16 PM
To: Valloud, Andres
Cc: vwnc NC
Subject: Re: [vwnc] [BUG] in digit logic



On Wed, Apr 14, 2010 at 6:12 PM, Eliot Miranda <[hidden email]> wrote:


On Wed, Apr 14, 2010 at 5:33 PM, Valloud, Andres <[hidden email]> wrote:
I am not sure what to think about it.  Try this C code:

#include <stdio.h>

int main() {

   printf("%lx & %lx is %lx.\n", -(1L << 31), -(1L << 31) - 1, -(1L <<
31) & (-(1L << 31) - 1));
   printf("%i & %i is %i.\n", -(1 << 31), -(1 << 31) - 1, -(1 << 31) &
(-(1 << 31) - 1));
   return;
}


The first line does your calculation with 64 bit signed ints and outputs
the result in hex (the compiler is on a 64 bit platform).  The second
line does your calculations with 32 bit signed ints, and outputs the
results in decimal.  The resulting program produces the following:

ffffffff80000000 & ffffffff7fffffff is ffffffff00000000.
-2147483648 & 2147483647 is 0.

Smalltalk matches the second line with 32 bit integers.  Now, your
example involves large negative integers 4 bytes long.  Note that large
negative integers are stored as large integers plus a sign bit.  This
implies large negative integers in Smalltalk are meant to be just as
large as necessary.  Otherwise, they would have to be infinitely large
because there is no limit to the size of a large negative integer.  In
other words, all the "leading Fs" are removed because large negative
integers do not have a fixed size.  In the C program above, using 64 bit
ints resulted in 8 leading Fs.  How many leading Fs should negative
large integers assume?  Are you still thinking this is a bug?

-1 is an infinite string of 1's (*).  Hence (-1 bitAnd: anyInteger) = anyInteger.
 
Hence negative something bitAnd: negative some other thing is negative something else.  The issue is only how many bytes negative something else requires and whether this fits in a SmallInteger or a LargeNegativeInteger of suitable size.

(*) note that the infinite string of 1's has a compact representation, namely SmallInteger -1.  But that does /not/ imply that (-1 bitAt: i) = 0 for i > 0 ever.

HTH
Eliot

and since C doesn't implement infinite precision arithmetic, whatever C has to say on the matter is deeply suspect when not outright wrong.
 
best
Eliot

P.S.  I will not hit Send before I have read and understood my post, and verified it is complete.
         I will not hit Send before I have read and understood my post, and verified it is complete.
         I will not hit Send before I have read and understood my post, and verified it is complete.
         I will not hit Send before I have read and understood my post, and verified it is complete.
...
(to the opening music of The Simpsons)



Andres.

-----Original Message-----
From: [hidden email] [mailto:[hidden email]] On
Behalf Of nicolas cellier
Sent: Wednesday, April 14, 2010 12:48 PM
To: [hidden email]
Subject: [vwnc] [BUG] in digit logic

Hi guys,
Try this code and tell me what you think:

(1 to: 80) reject: [:n |
  ((2 raisedTo: n) negated bitAnd: (2 raisedTo: n) negated - 1)
  = (2 raisedTo: n + 1) negated].

Answer is at http://bugs.squeak.org/view.php?id=6874
I'm a bit surprised to encounter this one in VW7.7...
But hey, it must be a very old bug !

Nicolas

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc



_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [BUG] in digit logic

Nicolas Cellier
Valloud, Andres <avalloud <at> cincom.com> writes:

>
>
> > and since C doesn't implement infinite precision
> arithmetic, whatever C has to say on the matter is deeply suspect when not
> outright wrong.
>
>  
> I think it's illustrative to see what happens with 64
> bit integers as opposed to 32 bit integers.  So, as you say, if you
> consider the infinite precision large negative integers, and then see
> them as an extreme case of increasing the integer size in C, you'd be
> forced into an endless tail of leading 0xF nibbles.  So we don't do it, and
> then bitAnd: behaves "strange".
>
>  
> Also, note that Nicolas' test case was not something
> bitAnd: -1 exactly, hence the C test program.
>
>  
>
> Andres.

Yes, the C code was usefull !
It illustrates exactly the same bug as VW:
64 bits code works ok
32 bit groke the carry.

In Smalltalk, internal representation is not two-complement, but absolute value.
So problem of infinite serie of leading 1 does not exist (it's virtual).
And we can extend the precision one byte further if we need a carry.
The modification is minor, here it is if you want to try:

digitLogic: arg op: op length: len
  "Perform the indicated bit-wise operation between the
  reciever and arg.  This implementation depends on the
  fact that new Integers are initialized to be all zeros"

  | result neg1 neg2 rneg z1 z2 rz b1 b2 b rdigits |
  neg1 := self negative.
  neg2 := arg negative.
  rneg :=
    ((neg1 ifTrue: [-1] ifFalse: [0])
      perform: op
      with: (neg2
          ifTrue: [-1]
          ifFalse: [0])) < 0.
  result := Integer new: len neg: rneg.
  rz := z1 := z2 := true.
  rdigits := 1.
  1 to: result digitLength do:
    [:i |
    b1 := self digitAt: i.
    neg1
      ifTrue: [b1 := z1
            ifTrue: [b1 = 0
                  ifTrue: [0]
                  ifFalse:
                    [z1 := false.
                    256 - b1]]
            ifFalse: [255 - b1]].
    b2 := arg digitAt: i.
    neg2
      ifTrue: [b2 := z2
            ifTrue: [b2 = 0
                  ifTrue: [0]
                  ifFalse:
                    [z2 := false.
                    256 - b2]]
            ifFalse: [255 - b2]].
    b := b1 perform: op with: b2.
    b = 0 ifFalse: [rdigits := i].
    result
      digitAt: i
      put: (rneg
          ifTrue: [rz
              ifTrue: [b = 0
                  ifTrue: [0]
                  ifFalse: [rz := false.
                    256 - b]]
              ifFalse: [255 - b]]
          ifFalse: [b])].
  (rneg and: [result compressed = 0]) ifTrue: [
    ^(result growBy: 1)
      digitAt: len + 1 put: 1;
      compressed].
  rdigits < len ifTrue: [^(result growTo: rdigits) compressed].
  ^result compressed

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [BUG] in digit logic

Ralf Propach
In reply to this post by Nicolas Cellier
nicolas cellier wrote:

> Hi guys,
> Try this code and tell me what you think:
>
> (1 to: 80) reject: [:n |
>    ((2 raisedTo: n) negated bitAnd: (2 raisedTo: n) negated - 1)
>    = (2 raisedTo: n + 1) negated].
>
> Answer is at http://bugs.squeak.org/view.php?id=6874
> I'm a bit surprised to encounter this one in VW7.7...
> But hey, it must be a very old bug !
>
> Nicolas
>
> _______________________________________________
> vwnc mailing list
> [hidden email]
> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>
>

Created AR59901 for this.

The problem is that there are negative numbers that can be represented
as an n-bit LargeNegativeInteger, but cannot be represented as n-bit Integers
with a twos-complement notation.
Easiest fix is to simply always use the next bigger size for the computation
of the result. In prLarge.c, in the largeBitLogic macro,
replace
        if (!newInteger(max(arg1.size,arg2.size), rneg, &result)) \

with
        if (!newInteger(max(arg1.size,arg2.size)+1, rneg, &result)) \

Ralf

--
Ralf Propach, [hidden email]
Tel: +49 231 975 99 38   Fax: +49 231 975 99 20
Georg Heeg eK (Dortmund)
Handelsregister: Amtsgericht Dortmund  A 12812
_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [BUG] in digit logic

Andres Valloud-6
Nice try with the Smalltalk side fix.  However, bitXor: shouldn't cause
negative results to grow...

-----Original Message-----
From: [hidden email] [mailto:[hidden email]] On
Behalf Of Ralf Propach
Sent: Thursday, April 15, 2010 4:03 AM
To: nicolas cellier; [hidden email]
Subject: Re: [vwnc] [BUG] in digit logic

nicolas cellier wrote:

> Hi guys,
> Try this code and tell me what you think:
>
> (1 to: 80) reject: [:n |
>    ((2 raisedTo: n) negated bitAnd: (2 raisedTo: n) negated - 1)
>    = (2 raisedTo: n + 1) negated].
>
> Answer is at http://bugs.squeak.org/view.php?id=6874
> I'm a bit surprised to encounter this one in VW7.7...
> But hey, it must be a very old bug !
>
> Nicolas
>
> _______________________________________________
> vwnc mailing list
> [hidden email]
> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>
>

Created AR59901 for this.

The problem is that there are negative numbers that can be represented
as an n-bit LargeNegativeInteger, but cannot be represented as n-bit
Integers with a twos-complement notation.
Easiest fix is to simply always use the next bigger size for the
computation of the result. In prLarge.c, in the largeBitLogic macro,
replace
        if (!newInteger(max(arg1.size,arg2.size), rneg, &result)) \

with
        if (!newInteger(max(arg1.size,arg2.size)+1, rneg, &result)) \

Ralf

--
Ralf Propach, [hidden email]
Tel: +49 231 975 99 38   Fax: +49 231 975 99 20
Georg Heeg eK (Dortmund)
Handelsregister: Amtsgericht Dortmund  A 12812
_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [BUG] in digit logic

Andres Valloud-6
... this is trickier than it seems :).

-----Original Message-----
From: [hidden email] [mailto:[hidden email]] On
Behalf Of Valloud, Andres
Sent: Thursday, May 27, 2010 11:39 PM
To: [hidden email]
Subject: Re: [vwnc] [BUG] in digit logic

Nice try with the Smalltalk side fix.  However, bitXor: shouldn't cause
negative results to grow...

-----Original Message-----
From: [hidden email] [mailto:[hidden email]] On
Behalf Of Ralf Propach
Sent: Thursday, April 15, 2010 4:03 AM
To: nicolas cellier; [hidden email]
Subject: Re: [vwnc] [BUG] in digit logic

nicolas cellier wrote:

> Hi guys,
> Try this code and tell me what you think:
>
> (1 to: 80) reject: [:n |
>    ((2 raisedTo: n) negated bitAnd: (2 raisedTo: n) negated - 1)
>    = (2 raisedTo: n + 1) negated].
>
> Answer is at http://bugs.squeak.org/view.php?id=6874
> I'm a bit surprised to encounter this one in VW7.7...
> But hey, it must be a very old bug !
>
> Nicolas
>
> _______________________________________________
> vwnc mailing list
> [hidden email]
> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>
>

Created AR59901 for this.

The problem is that there are negative numbers that can be represented
as an n-bit LargeNegativeInteger, but cannot be represented as n-bit
Integers with a twos-complement notation.
Easiest fix is to simply always use the next bigger size for the
computation of the result. In prLarge.c, in the largeBitLogic macro,
replace
        if (!newInteger(max(arg1.size,arg2.size), rneg, &result)) \

with
        if (!newInteger(max(arg1.size,arg2.size)+1, rneg, &result)) \

Ralf

--
Ralf Propach, [hidden email]
Tel: +49 231 975 99 38   Fax: +49 231 975 99 20
Georg Heeg eK (Dortmund)
Handelsregister: Amtsgericht Dortmund  A 12812
_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [BUG] in digit logic

Andres Valloud-6
In reply to this post by Nicolas Cellier
Watch out... the below section

    b = 0 ifFalse: [rdigits := i].
    result
      digitAt: i
      put: (rneg
          ifTrue: [rz
              ifTrue: [b = 0
                  ifTrue: [0]
                  ifFalse: [rz := false.
                    256 - b]]
              ifFalse: [255 - b]]
          ifFalse: [b])].

should be written like

        newDigit := (rneg ifTrue: [...] ifFalse: [...]).
        newDigit = 0 ifFalse: [rdigits := i].
        result
                digitAt: i
                put: newDigit

because otherwise expressions like

        -65515 digitLogic: -65515 op: #bitAnd: length: 2

fail to produce the correct result.

Andres.

-----Original Message-----
From: [hidden email] [mailto:[hidden email]] On Behalf Of nicolas cellier
Sent: Thursday, April 15, 2010 4:01 AM
To: [hidden email]
Subject: Re: [vwnc] [BUG] in digit logic

Valloud, Andres <avalloud <at> cincom.com> writes:

>
>
> > and since C doesn't implement infinite precision
> arithmetic, whatever C has to say on the matter is deeply suspect when
> not outright wrong.
>
>  
> I think it's illustrative to see what happens with 64 bit integers as
> opposed to 32 bit integers.  So, as you say, if you consider the
> infinite precision large negative integers, and then see them as an
> extreme case of increasing the integer size in C, you'd be forced into
> an endless tail of leading 0xF nibbles.  So we don't do it, and then
> bitAnd: behaves "strange".
>
>  
> Also, note that Nicolas' test case was not something
> bitAnd: -1 exactly, hence the C test program.
>
>  
>
> Andres.

Yes, the C code was usefull !
It illustrates exactly the same bug as VW:
64 bits code works ok
32 bit groke the carry.

In Smalltalk, internal representation is not two-complement, but absolute value.
So problem of infinite serie of leading 1 does not exist (it's virtual).
And we can extend the precision one byte further if we need a carry.
The modification is minor, here it is if you want to try:

digitLogic: arg op: op length: len
  "Perform the indicated bit-wise operation between the
  reciever and arg.  This implementation depends on the
  fact that new Integers are initialized to be all zeros"

  | result neg1 neg2 rneg z1 z2 rz b1 b2 b rdigits |
  neg1 := self negative.
  neg2 := arg negative.
  rneg :=
    ((neg1 ifTrue: [-1] ifFalse: [0])
      perform: op
      with: (neg2
          ifTrue: [-1]
          ifFalse: [0])) < 0.
  result := Integer new: len neg: rneg.
  rz := z1 := z2 := true.
  rdigits := 1.
  1 to: result digitLength do:
    [:i |
    b1 := self digitAt: i.
    neg1
      ifTrue: [b1 := z1
            ifTrue: [b1 = 0
                  ifTrue: [0]
                  ifFalse:
                    [z1 := false.
                    256 - b1]]
            ifFalse: [255 - b1]].
    b2 := arg digitAt: i.
    neg2
      ifTrue: [b2 := z2
            ifTrue: [b2 = 0
                  ifTrue: [0]
                  ifFalse:
                    [z2 := false.
                    256 - b2]]
            ifFalse: [255 - b2]].
    b := b1 perform: op with: b2.
    b = 0 ifFalse: [rdigits := i].
    result
      digitAt: i
      put: (rneg
          ifTrue: [rz
              ifTrue: [b = 0
                  ifTrue: [0]
                  ifFalse: [rz := false.
                    256 - b]]
              ifFalse: [255 - b]]
          ifFalse: [b])].
  (rneg and: [result compressed = 0]) ifTrue: [
    ^(result growBy: 1)
      digitAt: len + 1 put: 1;
      compressed].
  rdigits < len ifTrue: [^(result growTo: rdigits) compressed].
  ^result compressed

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [BUG] in digit logic

Nicolas Cellier
Valloud, Andres <avalloud <at> cincom.com> writes:

>
> snip...
>
> because otherwise expressions like
>
> -65515 digitLogic: -65515 op: #bitAnd: length: 2
>
> fail to produce the correct result.
>
> Andres.
>

Hi Andres,

above expression works in Squeak.

Nicolas

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [BUG] in digit logic

Andres Valloud-6
I took a quick look last night, and I *think* (I could be wrong!) the
code used by Squeak is not exactly the same as the code that was in the
original message here.  I thought I'd post about what I found with the
code in this mailing list.  I am glad the code in Squeak is not broken
further :).

-----Original Message-----
From: [hidden email] [mailto:[hidden email]] On
Behalf Of nicolas cellier
Sent: Friday, May 28, 2010 11:13 AM
To: [hidden email]
Subject: Re: [vwnc] [BUG] in digit logic

Valloud, Andres <avalloud <at> cincom.com> writes:

>
> snip...
>
> because otherwise expressions like
>
> -65515 digitLogic: -65515 op: #bitAnd: length: 2
>
> fail to produce the correct result.
>
> Andres.
>

Hi Andres,

above expression works in Squeak.

Nicolas

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [BUG] in digit logic

Nicolas Cellier
Valloud, Andres <avalloud <at> cincom.com> writes:

>
> I took a quick look last night, and I *think* (I could be wrong!) the
> code used by Squeak is not exactly the same as the code that was in the
> original message here.  I thought I'd post about what I found with the
> code in this mailing list.  I am glad the code in Squeak is not broken
> further :).
>
> -----Original Message-----
> From: vwnc-bounces <at> cs.uiuc.edu [mailto:vwnc-bounces <at> cs.uiuc.edu] On
> Behalf Of nicolas cellier
> Sent: Friday, May 28, 2010 11:13 AM
> To: vwnc <at> cs.uiuc.edu
> Subject: Re: [vwnc] [BUG] in digit logic
>
> Valloud, Andres <avalloud <at> cincom.com> writes:
>
> >
> > snip...
> >
> > because otherwise expressions like
> >
> > -65515 digitLogic: -65515 op: #bitAnd: length: 2
> >
> > fail to produce the correct result.
> >
> > Andres.
> >
>
> Hi Andres,
>
> above expression works in Squeak.
>
> Nicolas
>
> _______________________________________________
> vwnc mailing list
> vwnc <at> cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>


You are perfectly right...
This one should be ok.

digitLogic: arg op: op length: len
  "Perform the indicated bit-wise operation between the
  reciever and arg.  This implementation depends on the
  fact that new Integers are initialized to be all zeros"

  | result neg1 neg2 rneg z1 z2 rz b1 b2 b rdigits |
  neg1 := self negative.
  neg2 := arg negative.
  rneg :=
    ((neg1 ifTrue: [-1] ifFalse: [0])
      perform: op
      with: (neg2
          ifTrue: [-1]
          ifFalse: [0])) < 0.
  result := Integer new: len neg: rneg.
  rz := z1 := z2 := true.
  rdigits := 1.
  1 to: result digitLength do:
    [:i |
    b1 := self digitAt: i.
    neg1
      ifTrue: [b1 := z1
            ifTrue: [b1 = 0
                  ifTrue: [0]
                  ifFalse:
                    [z1 := false.
                    256 - b1]]
            ifFalse: [255 - b1]].
    b2 := arg digitAt: i.
    neg2
      ifTrue: [b2 := z2
            ifTrue: [b2 = 0
                  ifTrue: [0]
                  ifFalse:
                    [z2 := false.
                    256 - b2]]
            ifFalse: [255 - b2]].
    b := b1 perform: op with: b2.
    rneg
      ifTrue: [b := rz
            ifTrue: [b = 0
                ifTrue: [0]
                ifFalse:
                  [rz := false.
                  256 - b]]
            ifFalse: [255 - b]].
    b = 0 ifFalse: [rdigits := i].
    result digitAt: i put: b].
  (rneg and: [result compressed = 0]) ifTrue: [
    ^(result growBy: 1)
      digitAt: len + 1 put: 1;
      compressed].
  rdigits < len ifTrue: [^(result growTo: rdigits) compressed].
  ^result compressed

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc