XP is just a number PerlMonks

### Re^2: Integer overflow

by gone2015 (Deacon)
 on Apr 24, 2009 at 11:16 UTC Need Help??

in reply to Re: Integer overflow

my \$result = unpack "l", pack "l", 1729080737 + 72 * 14 * 425567;

In this case the arithmetic gives an unsigned 32-bit integer, and all is well...

...though I note it works because pack('l', ...) silently accepts a value outside -0x8000_0000..+0x7FFF_FFFF and packs away the LS 4 bytes of it's machine representation. I haven't found where that is documented... In this case that can be avoided by using pack('L', ...).

I wondered about more general/extreme cases, for example:

```my \$result = 1729080737 + 72 * 14 * 425567  + 0xFFFF_FFFF ;

print \$result, "\n" ;
print \$result & 0xFFFF_FFFF, "\n" ;
print unpack('l', pack('l', \$result)), "\n" ;
which works fine on 64 bit integer systems, but on a 32 bit one the result is:
```6453019568
4294967295
-1
```
because Perl happily does the arithmetic in ~54 bits of "integer in floating point form" (assuming IEEE-754 double), but when an integer in integer form is required, gives 0xFFFF_FFFF for anything > 0xFFFF_FFFF (and -0x8000_0000 for anything < -0x8000_0000) even if the operation would happily mask down to 32 bits :-( I don't know of a simple way to persuade Perl to give the LS 32 bits of an integer which may or may not be held as a float.

use integer wrapped around the arithmetic gives the expected result on both 32 and 64 bit systems.

Avoiding pack (in order to avoid giving an out of range argument) is a bit messy, but I believe this works for both 64 and 32 bit systems:

```  { my \$q   = \$result & 0xFFFF_FFFF ;
\$result = \$q <= 0x7FFF_FFFF ? \$q : -1 - (\$q ^ 0xFFFF_FFFF) ;
} ;

Replies are listed 'Best First'.
Re^3: Integer overflow
by MishaMoose (Scribe) on Dec 03, 2010 at 15:03 UTC

Well this explains why none of my standard approaches to determining overflow work in Perl. I had discovered that any overflow was capped rather than rolling over but I was pulling my hair our for a while as to 'WHY' until I googled for 'perl integer overflow' and found this thread. Many Thanks !!

Misha/Michael - Russian student, grognard, bemused observer of humanity and self professed programmer with delusions of relevance
Re^3: Integer overflow
by Your Mother (Archbishop) on Apr 24, 2009 at 20:44 UTC

I'm trying to be less obtuse about this kind of thing; finally buckle down and learn applied bit ops and hex math and friends. Do you think you could walk (me) through exactly what's going on in this block?

```  { my \$q   = \$result & 0xFFFF_FFFF ;
\$result = \$q <= 0x7FFF_FFFF ? \$q : -1 - (\$q ^ 0xFFFF_FFFF) ;
} ;

OK...

```  { my \$q   = \$result & 0xFFFF_FFFF ;
\$result = \$q <= 0x7FFF_FFFF ? \$q : -1 - (\$q ^ 0xFFFF_FFFF) ;
} ;
...the objective is to take the LS 32 bits of an integer, 32 bit or more, signed or unsigned, and set \$result to be the signed 32 bit integer value. So:

1. \$result & 0xFFFF_FFFF extracts the LS 32 bits and returns an unsigned value.

2. if the value is now <= 0x7FFF_FFFF, then it's positive, and we're done...

3. ...otherwise we have 0x8000_0000..0xFFFF_FFFF which we need to map to -0x8000_0000..-0x0000_0001. The XOR \$q ^ 0xFFFF_FFFF gives 0x7FFF_FFFF..0x0000_0000, so we complete the process by negating that and subtracting 1... or subtracting that from -1.

This could also be written -((\$q ^ 0xFFFF_FFFF) + 1)or -((~\$q + 1) & 0xFFFF_FFFF)... which are closer to the conventional way of changing the sign -- noting that we want this to work for any size of integer from 32 up.

This is assuming 2's complement signed integers. I cannot recall a sign and magnitude machine (for integers). The last 1's complement machine I worked on was a CDC6400 in the 70's. So it's a fairly safe assumption.

But, you could always: unpack('l', pack('L', \$result & 0xFFFF_FFFF)), which ensures a valid argument for pack('L', ...) and makes no assumptions about how unpack('l', ...) interprets the bits.

Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://759804]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (5)
As of 2024-02-23 03:08 GMT
Voting Booth?
My favourite way to spend a leap day ...

Results (22 votes). Check out past polls.