# 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

```