In search of a module ...

Andy Armstrong andy at hexten.net
Tue Feb 19 18:58:11 GMT 2008


On 19 Feb 2008, at 18:34, David Cantrell wrote:
> Do any of you know of a module that implements 2s-complement  
> arithmetic
> on fixed-size integers?
>
> I realise that on any sane machine (maybe even on every machine perl
> runs on) the underlying signed ints are 2s-complement, but I need to  
> do
> 2s-complement mathemagics on perl scalars, not C ints.


I think I may know what this is about :)

If you assume the underlying architecture is 2s comp and your word  
length is shorter than the native integer most operations will be fine  
if you just mask the result. Signed arithmetic isn't actually signed  
for most operations - in the sense that the sign bit doesn't need  
special treatment. So 8 bit addition is

$r = ($a + $b) & 0xFF;

or if you want carry (in and out):

$t  = $a + $b + $carry;		# include carry in
$nc = ($t & 0x100) >> 8;	# carry out
$r  = $t & 0xFF;

The same applies to subtraction although, if you want to make it  
general, you need to watch out for things like the Z80 inverting the  
sense of the sign bit in subtractions. Logically the carry flag should  
be set before the subtraction so you can find out whether the sub had  
to borrow from it - but the Z80 (and 8080) clears carry before the  
operation and then sets it if the operation had to borrow from it. On  
the 6502 C is like a virtual ninth bit on the value on the LHS, on the  
Z80 it's complemented.

The only operation on an 8 bit CPU that's really sign-aware is  
arithmetic shift right - which has to sign extend:

$r = ($a >> 1) | ($a & 0x80);

-- 
Andy Armstrong, Hexten






More information about the london.pm mailing list