<LargePositiveInteger>>BitAnd:> method not needed

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

<LargePositiveInteger>>BitAnd:> method not needed

Ralph Boland
I am using Squeak  3.11.  I assume the same results apply to Squeak 4.4.  If not, my apologies.

In Squeak if I evaluate:

1)  ((2 << 256)  bitAnd: (2 << 128)) ==>  0
2)  ((2 << 256)  bitAnd: (2 << 128)) class ==> SmallInteger
3)  (2 << 128)                               ==>  680564733841876926926749214863536422912
4)  ((2 << 128) bitAnd: (2 << 128))  ==>  680564733841876926926749214863536422912

This all looks correct and I care because I need to do <bitAnd:> of some largePositiveIntegers.

But <LargePositiveInteger>>BitAnd:>  is:

"Primitive. Answer an Integer whose bits are the logical AND of the
    receiver's bits and those of the argument. Fail if the receiver or argument
    is greater than 32 bits. See Object documentation whatIsAPrimitive."
    <primitive: 14>
    self halt.          "I ADDED THE HALT"
    ^ super bitAnd: anInteger

The way I see it  <LargePositiveInteger>>BitAnd:>   is always going to fail and thus invoke its super version
(<LargePositiveInteger>>BitAnd:>)  and this is what I see when I run the code; i.e. I hit the halt.

So why have <LargePositiveInteger>>BitAnd:> method at all?

Ditto for the other bit operations.

Ralph Boland


Reply | Threaded
Open this post in threaded view
|

Re: <LargePositiveInteger>>BitAnd:> method not needed

Levente Uzonyi-2
On Thu, 20 Jun 2013, Ralph Boland wrote:

> I am using Squeak  3.11.  I assume the same results apply to Squeak 4.4.  If not, my apologies.

LargePositiveInteger >> #bitAnd: is not present in Squeak 4.4.

>
> In Squeak if I evaluate:
>
> 1)  ((2 << 256)  bitAnd: (2 << 128)) ==>  0
> 2)  ((2 << 256)  bitAnd: (2 << 128)) class ==> SmallInteger
> 3)  (2 << 128)                               ==>  680564733841876926926749214863536422912
> 4)  ((2 << 128) bitAnd: (2 << 128))  ==>  680564733841876926926749214863536422912
>
> This all looks correct and I care because I need to do <bitAnd:> of some largePositiveIntegers.
>
> But <LargePositiveInteger>>BitAnd:>  is:
>
> "Primitive. Answer an Integer whose bits are the logical AND of the
>     receiver's bits and those of the argument. Fail if the receiver or argument
>     is greater than 32 bits. See Object documentation whatIsAPrimitive."
>     <primitive: 14>
>     self halt.          "I ADDED THE HALT"
>     ^ super bitAnd: anInteger
>
> The way I see it  <LargePositiveInteger>>BitAnd:>   is always going to fail and thus invoke its super version
> (<LargePositiveInteger>>BitAnd:>)  and this is what I see when I run the code; i.e. I hit the halt.
>
> So why have <LargePositiveInteger>>BitAnd:> method at all?
As the comment says: primitive 14 works for nonnegative SmallIntegers and
all LargePositiveIntegers which can be represented in 4 bytes, so all
values up to 4294967295.

In your image the following expression should use the primitive:

  4294967295 bitAnd: 1

In this case the primitive should fail:

  4294967296 bitAnd: 1


Levente

>
> Ditto for the other bit operations.
>
> Ralph Boland
>
>

Reply | Threaded
Open this post in threaded view
|

Re: <LargePositiveInteger>>BitAnd:> method not needed

Nicolas Cellier
Note that some times ago, Andreas and Eliot have added primitives exploiting the ubiquitous possibility of performing 64 bits arithmetic in underlying C language with modern compilers.

So there is also InterpreterPrimitives>>#primitiveBitAndLargeIntegers which works for positive integer receiver and arguments up to 64 bits and is currently connected to primitive 34 in both Interpreter and COG VM.

So a possible strategy would be to invoke <primitive: 34> from LargePositiveInteger and fall back to super if failed. That may speed up some operations on "Small" large integers, and will add a bit more delay for "Large" and negative Large integers. Up to you to peek a sufficiently recent VM and test...


2013/6/21 Levente Uzonyi <[hidden email]>
On Thu, 20 Jun 2013, Ralph Boland wrote:

I am using Squeak  3.11.  I assume the same results apply to Squeak 4.4.  If not, my apologies.

LargePositiveInteger >> #bitAnd: is not present in Squeak 4.4.



In Squeak if I evaluate:

1)  ((2 << 256)  bitAnd: (2 << 128)) ==>  0
2)  ((2 << 256)  bitAnd: (2 << 128)) class ==> SmallInteger
3)  (2 << 128)                               ==>  680564733841876926926749214863536422912
4)  ((2 << 128) bitAnd: (2 << 128))  ==>  680564733841876926926749214863536422912

This all looks correct and I care because I need to do <bitAnd:> of some largePositiveIntegers.

But <LargePositiveInteger>>BitAnd:>  is:

"Primitive. Answer an Integer whose bits are the logical AND of the
    receiver's bits and those of the argument. Fail if the receiver or argument
    is greater than 32 bits. See Object documentation whatIsAPrimitive."
    <primitive: 14>
    self halt.          "I ADDED THE HALT"
    ^ super bitAnd: anInteger

The way I see it  <LargePositiveInteger>>BitAnd:>   is always going to fail and thus invoke its super version
(<LargePositiveInteger>>BitAnd:>)  and this is what I see when I run the code; i.e. I hit the halt.

So why have <LargePositiveInteger>>BitAnd:> method at all?

As the comment says: primitive 14 works for nonnegative SmallIntegers and all LargePositiveIntegers which can be represented in 4 bytes, so all values up to 4294967295.

In your image the following expression should use the primitive:

        4294967295 bitAnd: 1

In this case the primitive should fail:

        4294967296 bitAnd: 1


Levente



Ditto for the other bit operations.

Ralph Boland







Reply | Threaded
Open this post in threaded view
|

Re: <LargePositiveInteger>>BitAnd:> method not needed

Nicolas Cellier
And as a complement, primitive 14 which is connected to  InterpreterPrimitives>>#primitiveBitAnd effectively works for positive receiver and argument up to 32 bits.

Bear in mind that SmallInteger maxVal highBit = 30, so it did make sense to try up to 32 bits.

Yet another strategy would be to connect primitive 34 everywhere both in small and large ints...



2013/6/21 Nicolas Cellier <[hidden email]>
Note that some times ago, Andreas and Eliot have added primitives exploiting the ubiquitous possibility of performing 64 bits arithmetic in underlying C language with modern compilers.

So there is also InterpreterPrimitives>>#primitiveBitAndLargeIntegers which works for positive integer receiver and arguments up to 64 bits and is currently connected to primitive 34 in both Interpreter and COG VM.

So a possible strategy would be to invoke <primitive: 34> from LargePositiveInteger and fall back to super if failed. That may speed up some operations on "Small" large integers, and will add a bit more delay for "Large" and negative Large integers. Up to you to peek a sufficiently recent VM and test...


2013/6/21 Levente Uzonyi <[hidden email]>
On Thu, 20 Jun 2013, Ralph Boland wrote:

I am using Squeak  3.11.  I assume the same results apply to Squeak 4.4.  If not, my apologies.

LargePositiveInteger >> #bitAnd: is not present in Squeak 4.4.



In Squeak if I evaluate:

1)  ((2 << 256)  bitAnd: (2 << 128)) ==>  0
2)  ((2 << 256)  bitAnd: (2 << 128)) class ==> SmallInteger
3)  (2 << 128)                               ==>  680564733841876926926749214863536422912
4)  ((2 << 128) bitAnd: (2 << 128))  ==>  680564733841876926926749214863536422912

This all looks correct and I care because I need to do <bitAnd:> of some largePositiveIntegers.

But <LargePositiveInteger>>BitAnd:>  is:

"Primitive. Answer an Integer whose bits are the logical AND of the
    receiver's bits and those of the argument. Fail if the receiver or argument
    is greater than 32 bits. See Object documentation whatIsAPrimitive."
    <primitive: 14>
    self halt.          "I ADDED THE HALT"
    ^ super bitAnd: anInteger

The way I see it  <LargePositiveInteger>>BitAnd:>   is always going to fail and thus invoke its super version
(<LargePositiveInteger>>BitAnd:>)  and this is what I see when I run the code; i.e. I hit the halt.

So why have <LargePositiveInteger>>BitAnd:> method at all?

As the comment says: primitive 14 works for nonnegative SmallIntegers and all LargePositiveIntegers which can be represented in 4 bytes, so all values up to 4294967295.

In your image the following expression should use the primitive:

        4294967295 bitAnd: 1

In this case the primitive should fail:

        4294967296 bitAnd: 1


Levente



Ditto for the other bit operations.

Ralph Boland