50+ bits of arithmetic in a 32-bit bag

Discussion in 'Perl Misc' started by mailbox@cpacker.org, Aug 9, 2006.

  1. Guest

    Our implementation of Perl under AIX
    doesn't support 64-bit integer arithmetic;
    so says "perl -V".

    A search of these newsgroups turned up a
    test of this fact as follows:

    $two += 2;
    $x = $two ** 63 + 25;
    $y = $two ** 63 + 30;
    if($x == $y) {print "64 bits not supported\n"}
    else {print "64 bits supported\n"}

    I found that it would give an affirmative
    result if I used up to 55 instead of 63.
    This suggests that a floating-point
    format with a seven-byte fraction is
    being invoked. Perhaps that's the native
    floating-point of the AIX box?
    At any rate, barring followups to the
    contrary, I'll assume that I can treat
    our Perl as having a 55-bit integer
    arithmetic capability for accumulating
    sums, at least. The code in question
    doesn't have to be portable.

    --
    Charles Packer
    mailboxATcpacker.org
    http://cpacker.org/whatnews
     
    , Aug 9, 2006
    #1
    1. Advertising

  2. Guest

    wrote:
    > Our implementation of Perl under AIX
    > doesn't support 64-bit integer arithmetic;
    > so says "perl -V".
    >
    > A search of these newsgroups turned up a
    > test of this fact as follows:
    >
    > $two += 2;
    > $x = $two ** 63 + 25;
    > $y = $two ** 63 + 30;
    > if($x == $y) {print "64 bits not supported\n"}
    > else {print "64 bits supported\n"}
    >
    > I found that it would give an affirmative
    > result if I used up to 55 instead of 63.
    > This suggests that a floating-point
    > format with a seven-byte fraction is
    > being invoked. Perhaps that's the native
    > floating-point of the AIX box?
    > At any rate, barring followups to the
    > contrary, I'll assume that I can treat
    > our Perl as having a 55-bit integer
    > arithmetic capability for accumulating
    > sums, at least.


    That is a poor assumption. Just because the $x and $y are not identical
    does not mean that they are what they are supposed to be.

    On my machine, your test also passes for 55, but a more rigorous test
    does not:

    $ perl -le '$foo=55; print((2**$foo+30)-(2**$foo+25))'
    8

    I'm pretty sure that 5 != 8, so 55 bits is right out. On my machine, 52 is
    high as I would go.

    $ perl -le '$foo=52; foreach (1..1e7) { my $y =
    ((2**$foo+$_+1)-(2**$foo+$_));
    die $_ unless $y == 1}'


    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
     
    , Aug 9, 2006
    #2
    1. Advertising

  3. Guest

    wrote:
    > On my machine, your test also passes for 55, but a more rigorous test
    > does not:
    >
    > $ perl -le '$foo=55; print((2**$foo+30)-(2**$foo+25))'
    > 8
    >
    > I'm pretty sure that 5 != 8, so 55 bits is right out. On my machine, 52 is
    > high as I would go.
    >
    > $ perl -le '$foo=52; foreach (1..1e7) { my $y =
    > ((2**$foo+$_+1)-(2**$foo+$_));
    > die $_ unless $y == 1}'



    Thanks for that improvement! It behaves the same on our machine as on
    yours. Fortunately, 52 bits is still plenty of magnitude for our
    purposes.

    --
    Charles Packer
    mailboxATcpacker.org
    http://cpacker.org/whatnews
     
    , Aug 10, 2006
    #3
  4. -berlin.de Guest

    <> wrote in comp.lang.perl.misc:
    > wrote:
    > > Our implementation of Perl under AIX
    > > doesn't support 64-bit integer arithmetic;
    > > so says "perl -V".
    > >
    > > A search of these newsgroups turned up a
    > > test of this fact as follows:
    > >
    > > $two += 2;
    > > $x = $two ** 63 + 25;
    > > $y = $two ** 63 + 30;
    > > if($x == $y) {print "64 bits not supported\n"}
    > > else {print "64 bits supported\n"}
    > >
    > > I found that it would give an affirmative
    > > result if I used up to 55 instead of 63.
    > > This suggests that a floating-point
    > > format with a seven-byte fraction is
    > > being invoked. Perhaps that's the native
    > > floating-point of the AIX box?
    > > At any rate, barring followups to the
    > > contrary, I'll assume that I can treat
    > > our Perl as having a 55-bit integer
    > > arithmetic capability for accumulating
    > > sums, at least.

    >
    > That is a poor assumption. Just because the $x and $y are not identical
    > does not mean that they are what they are supposed to be.
    >
    > On my machine, your test also passes for 55, but a more rigorous test
    > does not:
    >
    > $ perl -le '$foo=55; print((2**$foo+30)-(2**$foo+25))'
    > 8
    >
    > I'm pretty sure that 5 != 8, so 55 bits is right out. On my machine, 52 is
    > high as I would go.
    >
    > $ perl -le '$foo=52; foreach (1..1e7) { my $y =
    > ((2**$foo+$_+1)-(2**$foo+$_));
    > die $_ unless $y == 1}'


    That happens to coincide with the 53 bit mantissa in IEEE-something
    floats. One bit is the sign bit, so 52 bits are safe.

    Anno
     
    -berlin.de, Aug 10, 2006
    #4
  5. Uri Guttman Guest

    >>>>> "m" == mailbox <> writes:

    m> wrote:
    >> On my machine, your test also passes for 55, but a more rigorous test
    >> does not:
    >>
    >> $ perl -le '$foo=55; print((2**$foo+30)-(2**$foo+25))'
    >> 8
    >>
    >> I'm pretty sure that 5 != 8, so 55 bits is right out. On my machine, 52 is
    >> high as I would go.
    >>
    >> $ perl -le '$foo=52; foreach (1..1e7) { my $y =
    >> ((2**$foo+$_+1)-(2**$foo+$_));
    >> die $_ unless $y == 1}'



    m> Thanks for that improvement! It behaves the same on our machine as on
    m> yours. Fortunately, 52 bits is still plenty of magnitude for our
    m> purposes.

    it would be hard to use a cpu today that doesn't use ieee float formats
    (any perl vax users around? :). so that mantissa size for double floats
    (64 bits) will be the same for almost any common box today.

    and this one liner also shows the transition from integers to float:

    perl -le "print '2**', \$_, ': ', 2**\$_, ' - 1 = ', 2**\$_ - 1 for 47 .. 52"

    notice that the -1 stops working after 49 bits so that is the largest
    integer you can store in a double. note that this is a decimal issue so
    even if the mantissa is 53 bits, you can't operate with a 1 (decimal)
    because it takes 4 bits to hold a decimal digit. this is why this shows
    49 usable (in decimal) integer bits but the ieee format has 53 bits in
    the mantissa.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
     
    Uri Guttman, Aug 10, 2006
    #5
  6. [A complimentary Cc of this posting was sent to
    Uri Guttman
    <>], who wrote in article <>:
    > perl -le "print '2**', \$_, ': ', 2**\$_, ' - 1 = ', 2**\$_ - 1 for 47 .. 52"


    Converting to version which has a better chance to work in the shells' maze:

    perl -le 'print q(2**), $_, q:) ), 2**$_, q( - 1 = ), 2**$_ - 1 for 47 .. 52'
    2**47: 140737488355328 - 1 = 140737488355327
    2**48: 281474976710656 - 1 = 281474976710655
    2**49: 562949953421312 - 1 = 562949953421311
    2**50: 1.12589990684262e+15 - 1 = 1.12589990684262e+15
    2**51: 2.25179981368525e+15 - 1 = 2.25179981368525e+15
    2**52: 4.5035996273705e+15 - 1 = 4.5035996273705e+15

    > notice that the -1 stops working after 49 bits so that is the largest
    > integer you can store in a double.


    Nope. 53 bits is OK.

    > note that this is a decimal issue so even if the mantissa is 53
    > bits, you can't operate with a 1 (decimal) because it takes 4 bits
    > to hold a decimal digit.


    Nope, this is just a buggy Perl's convertion to string.

    perl -le 'print q(2**), $_, q:) ), sprintf(q(%.0f), 2**$_), q( - 1 = ), sprintf(q(%.f), 2**$_ - 1) for 47 .. 55'
    2**47: 140737488355328 - 1 = 140737488355327
    2**48: 281474976710656 - 1 = 281474976710655
    2**49: 562949953421312 - 1 = 562949953421311
    2**50: 1125899906842624 - 1 = 1125899906842623
    2**51: 2251799813685248 - 1 = 2251799813685247
    2**52: 4503599627370496 - 1 = 4503599627370495
    2**53: 9007199254740992 - 1 = 9007199254740991
    2**54: 18014398509481984 - 1 = 18014398509481984
    2**55: 36028797018963968 - 1 = 36028797018963968

    Hope this helps,
    Ilya
     
    Ilya Zakharevich, Aug 10, 2006
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. GGG
    Replies:
    10
    Views:
    12,635
    Donar
    Jul 6, 2006
  2. T.A.
    Replies:
    7
    Views:
    498
    Daniel T.
    Dec 3, 2006
  3. Why Tea

    Arithmetic for 32-bit and 64-bit machines

    Why Tea, Jan 9, 2008, in forum: C Programming
    Replies:
    10
    Views:
    681
    cr88192
    Jan 10, 2008
  4. johnny
    Replies:
    3
    Views:
    3,043
    Tomás Ó hÉilidhe
    Jan 9, 2009
  5. xyz
    Replies:
    2
    Views:
    828
Loading...

Share This Page