[squeak-dev] Two's Complement and Squeak Integers

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Tue Jun 16 21:20:58 UTC 2020


Hi Eric,
there are several simple snippets that might be useful.
One simple thing to transform n bits unsigned into n bits signed value is
    ^self - ((self bitAt: n) bitShift: n).

Transforming a signed value into an unsigned bit pattern can be obtained
with a simple
    ^self bitAnd: AllOnesMask.
where:
    AllOnesMask := (1 bitShift: n) - 1.

Also note that #bitInvert definition assuming two complement is:
     ^ -1 - self

Squeak assumes an infinite serie of bits. For limited register, that is:
     ^ -1 - self bitAnd: allOnesMask

Inversely you can negate a 2 complement bit pattern thru
    ^1 + (self bitXor: AllOnesMask) bitAnd: AllOnesMask

Of course, you cannot negate AllOneMask, case of overflow...


Le mar. 16 juin 2020 à 21:40, Eric Gade <eric.gade at gmail.com> a écrit :

> Thanks Dave!
>
> The TwosComplementRegister is a good package and will be a helpful guide
> -- thanks for pointing me to it.
>
> For posterity I want to post the key functionality here (which was in
> #asSignedInteger). It more or less describes how to take bits (as an
> ordered collection of some kind) that are already in two's complement
> negative format and convert them to a Squeak negative Integer:
>
> asSignedInteger
>
> self negative
> ifTrue: [^ ((bits reversed collect: [:e | e value not])
> inject: 0
> into: [:val :bit | bit value
> ifTrue: [val << 1 + 1]
> ifFalse: [val << 1]]) negated - 1]
> ifFalse: [^ self asUnsignedInteger]
>
> Thanks again,
>
> On Tue, Jun 16, 2020 at 2:19 PM David T. Lewis <lewis at mail.msen.com>
> wrote:
>
>> Try loading package TwosComplement from the SqueakMap loader, or
>> install it like this:
>>
>>   Installer ss project: 'TwosComplement';
>>       package: 'TwosComplement';
>>       install.
>>
>> Then inspect these:
>>
>>   TwosComplementRegister width: 8 value: -1.
>>
>>   255 asRegister: 8. "same as above but note the overflow bit is set"
>>
>>   TwosComplementRegister width: 64 value: -1.
>>
>> Dave
>>
>>
>> On Tue, Jun 16, 2020 at 02:09:15PM -0400, Eric Gade wrote:
>> > Hi Karl,
>> >
>> > Integer readFrom: '11111111' readStream base: 2.  ?
>> > >
>> >
>> > When I evaluate this in Squeak, the Integer produced is 255 (I need to
>> get
>> > from 255 to -1 -- and back again if possible).
>> >
>> > One hint that I've found in the image is that Integers respond to a
>> message
>> > #highBitOfMagnitude, which gives me the value of the most significant
>> bit
>> > in the integer. That is a starting point if I want to treat the bits in
>> > twos-complement: I can determine if the desired representation should be
>> > negative or positive. However, I'm not sure how to actually translate
>> the
>> > bits into a matching Squeak integer with the correct sign and value.
>> >
>> > Here is a more concrete explanation of my issue: In the implementation /
>> > simulation, Register objects store their values as Squeak Integers, and
>> > they are truncated at evaluation to be 32-bit integers. Some
>> instructions
>> > will treat a register as signed and others as unsigned. For unsigned
>> > treatment, there's no problem: Squeak always has the correct bit values
>> for
>> > what I need. I just need to figure out what to "do" with the integer in
>> the
>> > register when I want to treat it as signed. In the case of a value like
>> -1
>> > ('11111111') I can send that #highBitOfMagnitude to determine if it
>> should
>> > be a negative or positive value, but then what? I can't just send
>> > #negative, because that gives me -255
>> >
>> > PS - Perhaps at some point there was a #twosComplement method
>> implemented
>> > on Integers. There is an EToys object that is currently sending the
>> message
>> > (which has no implementors in 5.3 as far as I can see): SecurityManager
>> >>
>> > #asn1Integer:
>> >
>> > On Tue, Jun 16, 2020 at 1:44 PM karl ramberg <karlramberg at gmail.com>
>> wrote:
>> >
>> > > Integer readFrom: '11111111' readStream base: 2.  ?
>> > >
>> > > Best,
>> > > Karl
>> > >
>> > >
>> > >
>> > >
>> > > On Tue, Jun 16, 2020 at 6:36 PM Eric Gade <eric.gade at gmail.com>
>> wrote:
>> > >
>> > >> Hi everyone,
>> > >>
>> > >> I'm smack in the middle of making some RISC-V tools in Squeak, which
>> > >> means I'm dealing with a lot of low-level bit manipulation.
>> > >>
>> > >> One question I have is how best to deal with two's complement
>> > >> representations of integers in Squeak, and how to translate between
>> the
>> > >> different (positive v negative) values based on a given set of bits
>> (or a
>> > >> byteArray or whatever).
>> > >>
>> > >> For example, doing the following:
>> > >> -1 printStringBase: 2 nDigits: 8. "11111111"
>> > >> Gives the expected binary value "11111111"
>> > >>
>> > >> However (and as we should expect), evaluating the following:
>> > >> 2r11111111. "255"
>> > >>
>> > >> Gives the (again, expected) value 255.
>> > >>
>> > >> My question is: what is the best way to convert between the
>> complements
>> > >> in Squeak? How can I take 255, examine its bits, and get -1 as the
>> response
>> > >> (or convert in the reverse)? I'm assuming there are already ways to
>> deal
>> > >> with this, I just cannot find them.
>> > >>
>> > >> Thanks!
>> > >>
>> > >> --
>> > >> Eric
>> > >>
>> > >>
>> > >
>> >
>> > --
>> > Eric
>>
>> >
>>
>>
>>
>
> --
> Eric
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20200616/5765f422/attachment-0001.html>


More information about the Squeak-dev mailing list