Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

reliably test integer size for portable bit-fiddling?

by wollmers (Scribe)
on Dec 08, 2014 at 19:29 UTC ( [id://1109630]=perlquestion: print w/replies, xml ) Need Help??

wollmers has asked for the wisdom of the Perl Monks concerning the following question:

Hi monks,

for a module which uses a lot of bitwise operations I want to have it portable, thus test for 64 or 32 bit support, which seems to work like this:

helmut@raspberry2 ~ $ perl -e 'print length(pack('j', -1))*8,"\n";' 64

Will this work? I cannot test it, because even my raspberries have 64int-Perls.

Replies are listed 'Best First'.
Re: reliably test integer size for portable bit-fiddling?
by BrowserUk (Patriarch) on Dec 08, 2014 at 20:00 UTC

    Use Config and check the ivsize key:

    C:\test>perl -MConfig -E"say $Config{ ivsize }" 8 C:\test>\perl32\bin\perl -MConfig -le"print $Config{ ivsize }" 4

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      Thx, but if I can avoid loading Config, and the dependency on it, then pure Perl wins.

      root@raspberry2:/home/helmut# time perl -MConfig -E 'print $Config{ivs +ize};' 8 real 0m0.177s user 0m0.160s sys 0m0.010s root@raspberry2:/home/helmut# time perl -e 'print length(pack('j', -1 +))*8;' 64 real 0m0.028s user 0m0.020s sys 0m0.000s
        Config is a core module, so is always available.

        Your code seems to work fine here:

        C:\test>\perl32\bin\perl -e"print length(pack('j', -1))*8;" 32 C:\test>perl -e"print length(pack('j', -1))*8;" 64

        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
        Config is part of Perl, and is Pure Perl.
Re: reliably test integer size for portable bit-fiddling?
by Perlbotics (Archbishop) on Dec 08, 2014 at 19:57 UTC

    I think so. Perhaps, it is also an option for you to ask perl itself with the help of core module Config?

    perl -e 'use Config; print $Config{use64bitint} eq "define" ? "yes, " + : "not ", "64bit perl\n"'

    Result (here):

    yes, 64bit perl

      For that kind of inquiry, perl has extended use for the -V option, supporting regular expressions et all:

      $ perl -V:'use64bit(int|all)|[iu]vsize' ivsize='8'; use64bitall='define'; use64bitint='define'; uvsize='8';

      Enjoy, Have FUN! H.Merijn
Re: reliably test integer size for portable bit-fiddling? (~0)
by tye (Sage) on Dec 09, 2014 at 00:04 UTC

      Beautiful use of the Maths. ;)


      Dave

        *cough*
        $ perl -E " say log(~0)/log(2) " 31.9999999996641 $ perl -E " say int 0.999+log(~0)/log(2) " 32
      log(~0)/log(2)

      Hmm, I tried a similar idea (get the index of the highest bit), but it failed. Now I remember:

      helmut@w3:~$ perl -e 'print log(-1)/log(2),"\n";' Can't take log of -1 at -e line 1.

      Thx, this is extremely fast and IMHO reliable, because it tests the capabilty directly.

      Helmut "wollmers" Wollmersdorfer

      I figure for base2 stuff length is better than log (no need to worry about rounding/transcendental crap), e.g.,
      4*length sprintf'%x',~0

        Avoid the multiply:

        say length sprintf "%b", ~0;; 64

        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: reliably test integer size for portable bit-fiddling?
by Tux (Canon) on Dec 08, 2014 at 21:34 UTC

    The j format is still architecture depending, as the others already showed. If your perl has 64bit ints (even if the poiters are just 32bit), does q (or Q) work for you? (for portability, do not forget < or >). That won't work on 32-bit-only perl builds.

    $ perl -MDP -we'DHexDump pack "Q", 0x12345678' 0000 78 56 34 12 00 00 00 00 xV4..... $ perl -MDP -we'DHexDump pack "Q>", 0x12345678' 0000 00 00 00 00 12 34 56 78 .....4Vx $ perl -MDP -we'DHexDump pack "Q<", 0x12345678' 0000 78 56 34 12 00 00 00 00 xV4..... $ perl -V:uvsize uvsize='8'; other perl $ perl -V:uvsize uvsize='4'; $ perl -wle'print length pack "Q", 3' Invalid type 'Q' in pack at -e line 1.

    Enjoy, Have FUN! H.Merijn
      I had written once  use constant CAN_PACK_QUADS => !! eval { my $f = pack 'q'; 1 }; cause it dies when it can't
Re: reliably test integer size for portable bit-fiddling?
by DrHyde (Prior) on Dec 09, 2014 at 11:56 UTC
    The normal way to figure out how big your ints are is this:
    use constant MAXINT => ~0;
    which is quite a bit easier to read.
Re: reliably test integer size for portable bit-fiddling?
by danaj (Friar) on Dec 14, 2014 at 06:28 UTC

    I find: ~0 > 4294967295 to work and be simple/fast/understandable. Easier to follow at a glance than your pack, no time spent loading Config, no log() needed. If you use it a lot, make it a constant, e.g.

    use constant MAXBITS => (~0 > 4294967295) ? 64 : 32;

    A downside is that it assumes a 32-/64-bit world so isn't ready for 128-bit UVs if they every come. If you're already using the Config module or think it's more clear and don't care about the small load time, then I'd use that ($Config{uvsize}).

    A warning on using ~0: don't use it in a place where bigint, bignum, or integer may be loaded, because it will be -1. This shouldn't be an issue inside your module, but something to be aware of.

A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1109630]
Approved by Perlbotics
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (3)
As of 2024-04-20 02:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found