Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Re: emulate 32-bit on perl 64

by sundialsvc4 (Abbot)
on Jan 11, 2012 at 15:58 UTC ( #947373=note: print w/ replies, xml ) Need Help??


in reply to emulate 32-bit on perl 64

Probably the key improvement here is the use of hexadecimal notation:   0xffffffff instead of the corresponding, “magic” decimal.   As long as you are very careful to use unsigned arithmetic and specify bitmasks that are no larger than the integer-size you know that you are using, code like this ought to be transportable.   (It might not be readable, heh, but it ought to be int-length agnostic.)

I would almost edit my comment to say, don’t use “arithmetic” at all when you are bit-twiddling, as in code like this:

$num = $num - 4294967296 if $num > 4294967295; $num = $num + 4294967296 if $num < -2147483648;
  That’s nasty...   And I recognize at least one of those numbers, -2147483648, as an old, familiar 32-bit friend.   I also detect the presence of signed arithmetic, dependent upon the thirty-first bit being the sign-bit.   I suggest that this code should be rewritten to use bit-masking operators ... and to do so, perhaps, in a very specific way, as follows:

If you want to mash-off, say, all but the rightmost 31 bits of an integer quantity, you should take:   qty := qty and ( not 0x7fffffff );.   (I am not using Perl notation here, for clarity.)   The subexpression, (not 0x7fffffff), will evaluate to an int in which all bits are 1 except for the rightmost 31 bits, and it will do so correctly no matter what the sizeof(int) may be.

So, I suggest that you need to go through code like this (fortunately, it is a small piece of code), work out what it is doing and then rewrite it.   Construct a very thorough set of Test::More cases that you can run on both a 32-bit and a 64-bit system to prove that your rewrite is thoroughly correct.


Comment on Re: emulate 32-bit on perl 64
Download Code
Replies are listed 'Best First'.
Re^2: emulate 32-bit on perl 64
by Eliya (Vicar) on Jan 11, 2012 at 16:55 UTC
    As long as you are very careful to use unsigned arithmetic and specify bitmasks that are no larger than the integer-size you know that you are using, code like this ought to be transportable.

    Unfortunately, it's not always quite as simple in the general case.  For example, if the 32-bit code relies on specific overflow/wrap-over effects. Consider the following very simple case:

    my $result = (0xffffffff + 2) & 0xffffffff; print $result;

    Although the result is masked down to 32 bits, it differs depending on the perl being used:

    32-bit perl: 4294967295 64-bit perl: 1

    (I'm not saying it cannot be done, but it requires taking into account the specific overflow behavior, IV/UV to NV conversions of 32-bit perls, etc. — simple 0xffffffff AND-masking isn't enough.)

      Erm, *what*? Why does 32-bit perl (I just tested on MirBSD/i386, it does behave as you said) not wraparound? Urgh!

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://947373]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (8)
As of 2015-07-29 00:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (260 votes), past polls