Home > Archive > PERL Beginners > March 2004 > What is happening here
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
What is happening here
|
|
| Wc -Sx- Jones 2004-03-30, 1:30 am |
| What is happening here -
#! /usr/bin/perl
use strict;
use warnings;
my $count;
while(1) {
(++$count) ? $count += $count-- : $count += $count++;
print "$count\n"; exit if $count > 60_000;
sleep 1;
}
__END__
-Sx-
| |
| Andrew Gaffney 2004-03-30, 1:30 am |
| WC -Sx- Jones wrote:
> What is happening here -
>
> #! /usr/bin/perl
> use strict;
> use warnings;
>
> my $count;
>
> while(1) {
> (++$count) ? $count += $count-- : $count += $count++;
>
> print "$count\n"; exit if $count > 60_000;
> sleep 1;
> }
>
> __END__
> -Sx-
That is a damn good question. I'm not sure what results I was expecting when I ran it, but
it sure wasn't this:
3
15
63
255
1023
4095
16383
65535
--
Andrew Gaffney
Network Administrator
Skyline Aeronautics, LLC.
636-357-1548
| |
| R. Joseph Newton 2004-03-30, 3:31 am |
| Andrew Gaffney wrote:
> WC -Sx- Jones wrote:
>
> That is a damn good question. I'm not sure what results I was expecting when I ran it, but
> it sure wasn't this:
>
> 3
> 15
> 63
> 255
> 1023
> 4095
> 16383
> 65535
I'm stumped, also.I would have expected progressive 2**n -1 As far as I can tell, the test
in the conditional operation should always evaluate true. The preccedence of += and postfix
decrement should have decremented after the value had doubled. After printing, the number
should be re-incremented Sheesh--there no damn short-circuit on the evaluation!! Well, I'll
be darned! Only one of the two alternatives will be assigned, but both are evaluated. That
is why the following did not produce the same effects:
Greetings! E:\d_drive\perlStuff>perl -w
use strict;
use warnings;
my $count;
$count++;
while ($count <= 60000) {
$count = $count * 2 - 1;
$count = $count *
print "$count\n";
next unless $count <= 65534;
$count++;
sleep 1;
}
^Z
1
3
7
15
31
....
So---
Greetings! E:\d_drive\perlStuff>perl -w
use strict;
use warnings;
my $count;
while(1) {
if (++$count) {
$count += $count;
$count--;
my $alternative_yes = $count;
$count += $count;
$count++;
my $alternative_no = $count;
} else {
die "The impossible has happened! $!";
}
print "$count\n"; exit if $count > 60_000;
sleep 1;
}
^Z
3
15
63
255
1023
4095
16383
65535
Joseph
| |
| R. Joseph Newton 2004-03-30, 3:31 am |
| "R. Joseph Newton" wrote:
> Andrew Gaffney wrote:
>
[color=darkred]
> I'm stumped, also.I would have expected progressive 2**n -1 As far as I can tell, the test
> in the conditional operation should always evaluate true. The preccedence of += and postfix
> decrement should have decremented after the value had doubled. After printing, the number
> should be re-incremented Sheesh--there no damn short-circuit on the evaluation!! Well, I'll
> be darned! Only one of the two alternatives will be assigned, but both are evaluated. ...
>
It really is an object lesson in the dangers of using lvalued functions in void context, for their
side effects. The conditional operator is meant to return one of its alternative values. Unlike
the or and and operators, though, it does not short-circuit its evaluation. It seems to evaluate
the expressions for both alternatives, and then assign one or the other depending on the value of
the test. Since the conditiional operator is used in void context, there is no lvalue to receive
the primary product of the operation. The side effects here are the whoe show.
> while(1) {
> if (++$count) {
> $count += $count;
> $count--;
> my $alternative_yes = $count;
> $count += $count;
> $count++;
> my $alternative_no = $count;
> } else {
> die "The impossible has happened! $!";
> }
> print "$count\n"; exit if $count > 60_000;
> sleep 1;
> }
Joseph
| |
| R. Joseph Newton 2004-03-30, 3:31 am |
| Tim Johnson wrote:
> Apparently (++$count) evaluates to 0, but I can't figure out why.
Nope. Always true. It just doesn'yt matter. Bill sorta threw us a red herring here. Seeing the conditiional operator distracts your attention to thinking about the product of the conditional, which is not even used here. What does happen is that both
alternative
expressions get evaluated before the appropriate one is assigned [to The Void in this case]. It's all byproduct.
> So the second expression is evaluated first.
Nope. They are evaluated in order.
> From there it's pretty self-explanatory. (++$count) will always evaluate to TRUE, since it will only get higher, and the first expression is evaluated.
>
> Maybe someone can enlighten us to some of the lesser known properties of the -- and ++ operators? It's definitely counterintuitive.
Not at all. The only counter intuitive thing here is the lack of short-circuit in the evaluation of alternative values within the conditional. Now we know. As to the prefix [++$var, --$var] and postfix [$var++, $var--] operators, that also is pretty in
tuitive once
you get connected with it. If the increment operator precedes the variable name, it means "increment the variable then use its value." If the increment operator ifollows the identifier, it means "Use the current value, then increment the variable." Ver
y intuitive.
Joseph
| |
| Wc -Sx- Jones 2004-03-30, 12:33 pm |
| WC -Sx- Jones wrote:
> What is happening here -
> while(1) {
> (++$count) ? $count += $count-- : $count += $count++;
>
:) May I ask a different way?
#! /usr/bin/perl
use strict;
use warnings;
my $count;
my $str;
while(1) {
(++$count) ? $count += $count--
: $count += $count++;
$str = unpack("B32", pack("N", $count));
print "$count \tis binary $str\n";
exit if $count > 60_000;
sleep 1;
}
__END__
-Sx-
PS - I am admit that I am likely in the middle of
a nervous break-down LOL :)
BTW - Joseph was correct about the side-effects issue. :)
No one seemed to address the other data formats...
| |
| Jeff 'Japhy' Pinyan 2004-03-30, 1:31 pm |
| On Mar 30, WC -Sx- Jones said:
>my $count;
>
>while(1) {
> (++$count) ? $count += $count-- : $count += $count++;
>
> print "$count\n"; exit if $count > 60_000;
> sleep 1;
>}
The main problem is the PRECEDENCE. Your ? : line is run like so:
((++$count) ? ($count += $count--) : $count) += $count++;
That is, no matter what branch is used, += $count++ always happens. As it
turns out, ++$count is always true, so your code is:
while (1) {
++$count;
$count += $count--;
$count += $count++;
}
This is tricky business. When $count is, for instance, 10,
$count += $count--;
what happens is this: first, the right-hand side is evaluated, so the
value of $count is returned (10), and then $count has one subtracted from
it, so $count is 9. Then, 10 is added to $count's value, so $count ends
up being 19. On the next line,
$count += $count++;
it works very similarly: first, $count's value is returned on the
right-hand side, and then $count's value is incremented by 1. This means
we're adding 19 to 20, to get 39.
So the first line adds 1 to $count. The second line multiplies by 2 and
subtracts 1. The third line multiplies by 2 and adds 1. The net result
is adding one to $count, and then multiplying it by 4 and subtracting 1.
my $count = 0;
while (1) {
$count = ($count + 1) * 4 - 1;
print "$count\n";
exit if $count > 60_000;
}
--
Jeff "japhy" Pinyan japhy@pobox.com http://www.pobox.com/~japhy/
RPI Acacia brother #734 http://www.perlmonks.org/ http://www.cpan.org/
CPAN ID: PINYAN [Need a programmer? If you like my work, let me know.]
<stu> what does y/// stand for? <tenderpuss> why, yansliterate of course.
| |
| Wc -Sx- Jones 2004-03-30, 2:31 pm |
|
#! /usr/bin/perl
use strict;
use warnings;
my $count;
my $index;
my $str;
while (++$index) {
$count = $index;
while(1) {
(++$count) ? $count += $count--
: $count += $count++;
$str = unpack("B32", pack("N", $count));
print "$count \tis binary $str\n";
last if $count > 60_000;
sleep 1;
}
exit if $index > 255;
}
__END__
-Sx-
OK, I am done :)
| |
| Charles K. Clarkson 2004-03-30, 4:31 pm |
| WC -Sx- Jones <sx@insecurity.org> wrote:
:
: PS - I am admit that I am likely in the middle of
: a nervous break-down LOL :)
You should be in just the right frame of mind for delving into
Parse::RecDecent. :)
Charles K. Clarkson
--
Mobile Homes Specialist
254 968-8328
| |
| R. Joseph Newton 2004-03-30, 8:33 pm |
| WC -Sx- Jones wrote:
> WC -Sx- Jones wrote:
>
> :) May I ask a different way?
>
> #! /usr/bin/perl
> use strict;
> use warnings;
>
> my $count;
> my $str;
>
> while(1) {
> (++$count) ? $count += $count--
> : $count += $count++;
>
> $str = unpack("B32", pack("N", $count));
> print "$count \tis binary $str\n";
> exit if $count > 60_000;
> sleep 1;
> }
>
> __END__
> -Sx-
>
> PS - I am admit that I am likely in the middle of
> a nervous break-down LOL :)
>
> BTW - Joseph was correct about the side-effects issue. :)
> No one seemed to address the other data formats...
That is pretty much how I got there. Not that I would have to unpcak those
numbers--they're pretty much engreained onmy memory ever since an instructor
gave us the prefect number problem as an assignment. Definitely increased my
admiration for Euclid, who did not have the binary p[aradigm to work with.
To elaborate a little:
Greetings! E:\d_drive\perlStuff>perl -w
#!perl -w
use strict;
use warnings;
my $count;
while(1) {
if (++$count) { # on second round: $count == ($oringinal * 4 -
1) + 1 == $oringinal * 4
# $oringinal = $count == 1
$count += $count; # $count == $oringinal * 2
$count--; # $count == ($oringinal * 2) - 1
my $alternative_yes = $count; #dead code
$count += $count; # $count == (($oringinal * 2) - 1) * 2 == (($oringinal
* 2) * 2) - (1 * 2) == ($oringinal * 4) - 2
$count++; # $count == (($oringinal * 4) - 2) + 1 == $oringinal
* 4 - 1
my $alternative_no = $count; #dead code
} else {
die "The impossible has happened! $!";
}
print "$count\n"; exit if $count > 60_000;
sleep 1;
}
^Z
3
15
63
So the upshot is that the function essentially quadruples the base value for the
loop on each iteration, but prints a value one less than the base value.
The values above could be clearly exzpressed as
4 -1
16 -1
64 -1
256 -1
or
4 ** 1 - 1
4 ** 2 - 1
4 ** 3 -1
...with a bit of sleight of hand thrown in for spice.
Joseph
| |
| R. Joseph Newton 2004-03-30, 8:33 pm |
| Jeff 'japhy' Pinyan wrote:
> On Mar 30, WC -Sx- Jones said:
>
>
> The main problem is the PRECEDENCE. Your ? : line is run like so:
>
> ((++$count) ? ($count += $count--) : $count) += $count++;
Have you tested this? I don't see the precedence issue happening here. Could
you try duplicating these reults with code explicitly specifying the precedence
you show? I do not think you are going to find that the outer parentheses you
show represent the actual precedence. Remember that the ? and : are not
different operators, but different parts of the same operator. If the +=
operator has a higher precedence than ?, it will also have a higher precedence
than :.
Joseph
| |
| Paul Johnson 2004-03-30, 9:32 pm |
| On Tue, Mar 30, 2004 at 04:57:07PM -0800, R. Joseph Newton wrote:
> Jeff 'japhy' Pinyan wrote:
>
>
> Have you tested this? I don't see the precedence issue happening here. Could
> you try duplicating these reults with code explicitly specifying the precedence
> you show? I do not think you are going to find that the outer parentheses you
> show represent the actual precedence. Remember that the ? and : are not
> different operators, but different parts of the same operator. If the +=
> operator has a higher precedence than ?, it will also have a higher precedence
> than :.
$ perl -MO=Deparse,-p -e '(++$count) ? $count += $count-- : $count += $count++;'
(((++$count) ? ($count += ($count--)) : $count) += ($count++));
-e syntax OK
Jeff is spot on, as usual.
If this were C, I would be muttering something about sequence points and
undefined behaviour right now. Perl is not quite so strict in that
regard, but you can still get unexpected results by breaking some of
those rules, so it is generally best not to.
--
Paul Johnson - paul@pjcj.net
http://www.pjcj.net
| |
| Jeff 'Japhy' Pinyan 2004-03-31, 11:36 am |
| On Mar 30, R. Joseph Newton said:
>Jeff 'japhy' Pinyan wrote:
>
>
>Have you tested this? I don't see the precedence issue happening here.
>Could you try duplicating these reults with code explicitly specifying
>the precedence you show? I do not think you are going to find that the
>outer parentheses you show represent the actual precedence. Remember
>that the ? and : are not different operators, but different parts of the
>same operator. If the += operator has a higher precedence than ?, it
>will also have a higher precedence than :.
Yes, I have tested it, and it's documented. ?: binds TIGHTER than +=.
--
Jeff "japhy" Pinyan japhy@pobox.com http://www.pobox.com/~japhy/
RPI Acacia brother #734 http://www.perlmonks.org/ http://www.cpan.org/
CPAN ID: PINYAN [Need a programmer? If you like my work, let me know.]
<stu> what does y/// stand for? <tenderpuss> why, yansliterate of course.
|
|
|
|
|