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

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


Le mar. 16 juin 2020 à 23:20, Nicolas Cellier <
nicolas.cellier.aka.nice at gmail.com> a écrit :

> 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...
>
> err, you can not negate  (1 bitShift: n-1) of course...

>
> 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/c7809b6e/attachment.html>


More information about the Squeak-dev mailing list