Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Strange interaction of bigint and foreach

by Athanasius (Monsignor)
on Apr 11, 2013 at 12:54 UTC ( #1028141=perlquestion: print w/ replies, xml ) Need Help??
Athanasius has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I’ve been using the exponentiation operator ** in conjunction with the bigint pragma to generate large integral powers, which I need to be exact. After some debugging, I found the following:

#! perl use strict; use warnings; use bigint; print "\nWith two foreach loops:\n\n"; for my $i (12 .. 14) { for my $j (20 .. 22) { print $i ** $j, "\n"; } } print "\nWith an inner C-style for loop:\n\n"; for my $i (12 .. 14) { for (my $j = 20; $j <= 22; ++$j) { print $i ** $j, "\n"; } }

Output:

22:38 >perl 604_SoPW.pl With two foreach loops: 3.83375999244748e+021 4.60051199093697e+022 5.52061438912436e+023 1.90049637748808e+022 2.4706452907345e+023 3.21183887795486e+024 8.36682554252848e+022 1.17135557595399e+024 1.63989780633558e+025 With an inner C-style for loop: 3833759992447475122176 46005119909369701466112 552061438912436417593344 19004963774880799438801 247064529073450392704413 3211838877954855105157369 83668255425284801560576 1171355575953987221848064 16398978063355821105872896 22:38 >

As you can see, the inner foreach loop is somehow cancelling the effect of the use bigint pragma; but converting that loop into a C-style for loop fixes the problem and gives me the output I need.

So, what’s going on? Is this behaviour documented anywhere? Is it a bug?

Thanks,

Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Comment on Strange interaction of bigint and foreach
Select or Download Code
Re: Strange interaction of bigint and foreach
by moritz (Cardinal) on Apr 11, 2013 at 12:58 UTC

      Very strange and dangerous... Some workarounds:

      use strict; use warnings; use bigint; print "\nWith two foreach loops:\n\n"; for my $j (20 .. 22) { for my $i (12 .. 14) { print $i ** ($j+0), "\n"; } } print "\nWith two foreach loops:\n\n"; for my $j (20 .. 22) { for my $i (12 .. 14) { print (((0+$i) ** $j), "\n"); } } print "\nWith two foreach loops:\n\n"; for my $j (20 .. 22) { for my $i (12 .. 14) { print ((0+$i) ** ($j+0), "\n"); } }
Re: Strange interaction of bigint and foreach
by salva (Monsignor) on Apr 11, 2013 at 13:02 UTC
    This is a bug in perl, probably caused by the compiler optimizing the foreach(<constant range>) {} construction into a C-like loop internally in order to reduce memory usage.

    You can try reporting it to p5p.

    update: Even if the problem is the range operator, this is still IMO a bug in Perl. The range operator should be overloadable or at least it should use the overloaded + and < operators.

Re: Strange interaction of bigint and foreach
by Athanasius (Monsignor) on Apr 11, 2013 at 13:14 UTC

    Thanks to all for the quick responses! I was misled by the documentation for bigint, which begins:

    All operators (including basic math operations) are overloaded.

    Chalk this one up to experience! (But I have to say: Apart from this glitch, I’m finding bigint to be brilliant at what it does.)

    Cheers,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (11)
As of 2014-08-28 13:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (261 votes), past polls