Array index bug using concatenated numbers

Discussion in 'Perl Misc' started by John W. Krahn, Apr 25, 2004.

  1. I ran across this problem on the Perl beginners mailing list and am
    posting here because I am not running the current version of Perl and
    would like someone else to confirm this.

    The following code should demonstrate the problem:

    #!/usr/bin/perl
    use warnings;
    use strict;

    use constant X => 99;
    use constant Y => 99;
    my @array;
    my @check1;
    my @check2;
    my $diff = 0;

    for my $x ( 0 .. X ) {
    for my $y ( 0 .. Y ) {
    my $i = 0 + ( $x . $y );
    $array[ $i ] = int( rand ~0 );
    push @check1, $array[ $i ];
    }
    }

    for my $x ( 0 .. X ) {
    for my $y ( 0 .. Y ) {
    my $i = 0 + ( $x . $y );
    push @check2, $array[ $i ];
    if ( $check1[ $#check2 ] != $check2[ $#check2 ] ) {
    print "$x . $y $check1[$#check2] $check2[$#check2]\n";
    $diff++;
    }
    }
    }

    print "\n$diff differences from ", X, Y, " entries\n";

    __END__

    This _should_ print out "0 differences from 9999 entries" but on my
    computer I get 900 differences. If I change "my $i = 0 + ( $x . $y );"
    to "my $i = $x * 100 + $y;" it works correctly with 0 differences. This
    looks like a bug in array indexing.

    The original thread is at
    http://groups.google.com/groups?threadm=4087A478.18574.7F3DCA@localhost


    TIA
    John
    --
    use Perl;
    program
    fulfillment
     
    John W. Krahn, Apr 25, 2004
    #1
    1. Advertising

  2. John W. Krahn

    Bob Walton Guest

    John W. Krahn wrote:

    > I ran across this problem on the Perl beginners mailing list and am
    > posting here because I am not running the current version of Perl and
    > would like someone else to confirm this.
    >
    > The following code should demonstrate the problem:
    >
    > #!/usr/bin/perl
    > use warnings;
    > use strict;
    >
    > use constant X => 99;
    > use constant Y => 99;
    > my @array;
    > my @check1;
    > my @check2;
    > my $diff = 0;
    >
    > for my $x ( 0 .. X ) {
    > for my $y ( 0 .. Y ) {
    > my $i = 0 + ( $x . $y );
    > $array[ $i ] = int( rand ~0 );
    > push @check1, $array[ $i ];
    > }
    > }
    >
    > for my $x ( 0 .. X ) {
    > for my $y ( 0 .. Y ) {
    > my $i = 0 + ( $x . $y );
    > push @check2, $array[ $i ];
    > if ( $check1[ $#check2 ] != $check2[ $#check2 ] ) {
    > print "$x . $y $check1[$#check2] $check2[$#check2]\n";
    > $diff++;
    > }
    > }
    > }
    >
    > print "\n$diff differences from ", X, Y, " entries\n";
    >
    > __END__
    >
    > This _should_ print out "0 differences from 9999 entries" but on my
    > computer I get 900 differences. If I change "my $i = 0 + ( $x . $y );"
    > to "my $i = $x * 100 + $y;" it works correctly with 0 differences. This
    > looks like a bug in array indexing.
    >
    > The original thread is at
    > http://groups.google.com/groups?threadm=4087A478.18574.7F3DCA@localhost
    >

    ....


    > John
    >


    It appears like the "900 differences" result is correct. Consider
    $array[1000], for example. It contains undef. That's because the
    number 1000 was never made by the expression 0+($x.$y) -- there is not
    combination of $x and $y in the range 0..99 which will make that
    expression generate 1000. There are 10000 elements in @array, and 900
    of them contain undef. That's because the subscript values for each of
    these 900 elements were never generated in $i. This then implies that
    some other element of @array was assigned each time -- specifically, 900
    other elements got written twice (consider for example which element
    gets written when $x is 0 and $y is 11 versus when $x is 1 and $y is 1).
    So when @check2 is generated from @array, 900 array elements from
    @array had different results in them than when the results were stored
    in @check1. Thus 900 differences.

    HTH.
    --
    Bob Walton
    Email: http://bwalton.com/cgi-bin/emailbob.pl
     
    Bob Walton, Apr 25, 2004
    #2
    1. Advertising

  3. Also sprach Purl Gurl:

    > John W. Krahn wrote:
    >
    > (snipped)
    >
    >> The following code should demonstrate the problem:

    >
    >> int( rand ~0 );

    >
    > I am curious about this syntax for rand.
    >
    > Your ~0 is intended to perform what function?


    ~0 is the bitwise negation of, well, zero. If you have a 32bit wide
    integer, zero is represented as 0 x 32. If you negate each bit, you
    get 1 x 32 which is

    0xff 0xff 0xff 0xff

    and that gives 4294967295. For the 32bit case, this is ULONG_MAX.

    'int( rand ~0 )' will therefore return a random integer in the range of
    0 .. ULONG_MAX.

    Tassilo
    --
    $_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
    pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
    $_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval
     
    Tassilo v. Parseval, Apr 25, 2004
    #3
  4. John W. Krahn

    Joe Smith Guest

    John W. Krahn wrote:

    > for my $x ( 0 .. X ) {
    > for my $y ( 0 .. Y ) {
    > my $i = 0 + ( $x . $y );


    Let's see; if $x = 1 and $y = 23, then $i = "123".
    But then if $x = 12 and $y = 3, then $i = "123".
    Therefore $array[$i] is going to get clobbered because you told it to.

    As you noticed, changing the calculation of $i so that it does not
    produce any duplicates makes the "problem" go away.

    As does using proper indexing: $array[$x][$y] = "something";

    I see no bug here.
    -Joe
     
    Joe Smith, Apr 25, 2004
    #4
  5. On Sat, 24 Apr 2004 21:18:02 -0700, Purl Gurl <>
    wrote:

    >> int( rand ~0 );

    >
    >I am curious about this syntax for rand.
    >
    >Your ~0 is intended to perform what function?


    $ perl -MO=Deparse -le 'rand ~0'
    BEGIN { $/ = "\n"; $\ = "\n"; }
    rand 4294967295;
    -e syntax OK

    $ perldoc perlop


    Michele
    --
    you'll see that it shouldn't be so. AND, the writting as usuall is
    fantastic incompetent. To illustrate, i quote:
    - Xah Lee trolling on clpmisc,
    "perl bug File::Basename and Perl's nature"
     
    Michele Dondi, Apr 25, 2004
    #5
  6. Joe Smith wrote:
    >
    > John W. Krahn wrote:
    >
    > > for my $x ( 0 .. X ) {
    > > for my $y ( 0 .. Y ) {
    > > my $i = 0 + ( $x . $y );

    >
    > Let's see; if $x = 1 and $y = 23, then $i = "123".
    > But then if $x = 12 and $y = 3, then $i = "123".
    > Therefore $array[$i] is going to get clobbered because you told it to.
    >
    > As you noticed, changing the calculation of $i so that it does not
    > produce any duplicates makes the "problem" go away.
    >
    > As does using proper indexing: $array[$x][$y] = "something";
    >
    > I see no bug here.


    Thanks Joe, I really need to get more sleep, it should have been
    obvious! :)


    John
    --
    use Perl;
    program
    fulfillment
     
    John W. Krahn, Apr 26, 2004
    #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. dh
    Replies:
    0
    Views:
    334
  2. Shabam

    Form variable concatenated

    Shabam, Sep 16, 2005, in forum: HTML
    Replies:
    2
    Views:
    408
    Mark Parnell
    Sep 16, 2005
  3. dejan budimir
    Replies:
    6
    Views:
    375
    Rolf Magnus
    Jul 4, 2004
  4. bdb112
    Replies:
    7
    Views:
    272
    Steven D'Aprano
    Mar 18, 2009
  5. Tomasz Chmielewski

    sorting index-15, index-9, index-110 "the human way"?

    Tomasz Chmielewski, Mar 4, 2008, in forum: Perl Misc
    Replies:
    4
    Views:
    307
    Tomasz Chmielewski
    Mar 4, 2008
Loading...

Share This Page