Re: 0**0
by rob_au (Abbot) on Jan 16, 2003 at 15:57 UTC

There has been a long discussion on this indeterminate form of exponentials previously  See More Fun with Zero!, in particular the replies from ariels and tilly.
perl le 'print+unpack("N",pack("B32","00000000000000000000001000011000"))'  [reply] 

There has been a long discussion on this indeterminate form of exponentials previously  See More Fun with Zero!, in particular the replies from ariels and tilly.
Thanks, that's quite interesting! Unfortunately, I don't understand most of the mathematical explanations (tilly++ for explaining the thing in English) and I can't find if 0**0 == 1 in Perl is coincidental or defined behaviour (ie. can I depend on 0**0 to be 1?).
Juerd
 http://juerd.nl/
 spamcollector_perlmonks@juerd.nl (do not use).
 [reply] 
Re: 0**0
by scain (Curate) on Jan 16, 2003 at 15:49 UTC

 [reply] 
Re: 0**0
by belg4mit (Prior) on Jan 16, 2003 at 15:50 UTC

It is 1 on SunOS 5.8 as well. It's probably a POSIX
standard (not that I can easily tell since search engines
are still stuck in the alphanumeric stone age ;),
since it is both "right" and "wrong". Anything raised to
the zeroth power is defined as 1. Yet anything mulitplied
by zero is 0. So they picked something and ran with it?
Question #3
"zero to the zeroth power"

I'm not belgian but I play one on TV.
 [reply] 

 [reply] 
Re: 0**0
by AbigailII (Bishop) on Jan 16, 2003 at 16:40 UTC

# uname srvm
HPUX B.11.00 C 9000/712
# perl v
This is perl, version 4.0
$RCSfile: perl.c,v $$Revision: 4.0.1.8 $$Date: 1993/02/05 19:39:30 $
Patch level: 36
Copyright (c) 1989, 1990, 1991, Larry Wall
Perl may be copied only under the terms of either the Artistic License
+ or the
GNU General Public License, which may be found in the Perl 4.0 source
+kit.
# perl wle 'print 0**0'
pow: DOMAIN error
0
#
 [reply] [d/l] 

Juerd
 http://juerd.nl/
 spamcollector_perlmonks@juerd.nl (do not use).
 [reply] 

jkruck:<rue> % uname srvm
HPUX B.11.00 U 9000/800
jkruck:<rue> % perl v
This is perl, version 5.005_03 built for PARISC1.1
Copyright 19871999, Larry Wall
Perl may be copied only under the terms of either the Artistic License
+ or the
GNU General Public License, which may be found in the Perl 5.0 source
+kit.
Complete documentation for Perl, including FAQ lists, should be found
+on
this system using `man perl' or `perldoc perl'. If you have access to
+ the
Internet, point your browser at http://www.perl.com/, the Perl Home Pa
+ge.
jkruck:<rue> % perl wle 'print 0**0'
1
 [reply] [d/l] 

 [reply] 



Re: 0**0
by antirice (Priest) on Jan 16, 2003 at 21:32 UTC

Well, the logarithm seems to agree.
0**0 = 1
log(1) / log(0) = 0
For those of you who don't remember logs, they allow you to figure out the exponent needed to get y from x. i.e.
log(y) / log(x) = z for x != 1 (since log(1) = 0, avoid div by zero)
x**z = y
Yeah, my point doesn't seem very valuable, but that's how I cope with 0**0 = 1.
Update: I know that log(0) = infinity. I understand that I used the limit of log(1) / log(0) as log(0) approaches infinity (travelling from right) to get my answer that 0**0 = 1. Approaching from the left results in undef since log(x) does not exist (this is because e^{n} = x means that i is a factor of e, in which case n is even...in the integer sense, let's not cloud the issue with reals) and anything divided by nothing (not nothing in the zero sense but nothing in the undefined sense) doesn't exist.
In short, depends upon which side you're coming from. I like both answers, but you 0**0 = undef guys were giving the 0**0 = 1 people a hard time.
Another interesting note:
0**x = ? as x approaches 0 from the right would result in ? being 0. From the left again is undefined since 0**x = 1 / 0**x. Since 0**x = 0 for x > 0, you'd be dividing by 0 to give you the undefined value.
So let's see, the score stands:
0**0 = 1 => 1 point
0**0 = 0 => 1 point
0**0 = undef => 2 points
Hmmm...maybe somebody from my 0**0 = 1 team can boost our score again.
wait...
% perl le 'print 0**0'
1
Let's see the scores now:
0**0 = 0 => 1 point
0**0 = undef => 2 points
0**0 = 1 => since perl says so, infinite points
;) Sorry this is so long.  [reply] [d/l] 

Except log(0) = infinity; hence log(1)/log(0) = 0/infinity, which is just another indeterminate.
 [reply] 

 [reply] 



Re: 0**0
by Courage (Parson) on Jan 17, 2003 at 07:33 UTC

0**0 relied on underlying C library for elder perls, which is mostly 0 but could be domain error.
Currently, as I see in source code, file "pp.c", integer power is implemented in C, and it happen to result in "1", either by accident or intentionally.
Here is code excerpt from perl5.8.0 to demonstrate my point:
/* now we have integer ** positive integer.
foo & (foo  1) is zero only for a power of 2. */
if (!(baseuv & (baseuv  1))) {
/* We are raising powerof2 to postive integer.
The logic here will work for any base (even non
+integer
bases) but it can be less accurate than
pow (base,power) or exp (power * log (base)) wh
+en the
intermediate values start to spill out of the m
+antissa.
With powers of 2 we know this can't happen.
And powers of 2 are the favourite thing for per
+l
programmers to notice ** not doing what they me
+an. */
NV result = 1.0;
NV base = baseuok ? baseuv : (NV)baseuv;
int n = 0;
/* The logic is this.
x ** n === x ** m1 * x ** m2 where n = m1 + m2
so as 42 is 32 + 8 + 2
x ** 42 can be written as
x ** 32 * x ** 8 * x ** 2
I can calculate x ** 2, x ** 4, x ** 8 etc triv
+ially:
x ** 2n is x ** n * x ** n
So I loop round, squaring x each time
(x, x ** 2, x ** 4, x ** 8) and multiply the re
+sult
by the xvalue whenever that bit is set in the
+power.
To finish as soon as possible I zero bits in th
+e power
when I've done them, so that power becomes zero
+ when
I clear the last bit (no more to do), and the l
+oop
terminates. */
Courage, the Cowardly Dog  [reply] [d/l] 
Re: 0**0
by busunsl (Vicar) on Jan 17, 2003 at 07:20 UTC

 [reply] 

 [reply] 
Re: 0**0
by JaWi (Hermit) on Jan 16, 2003 at 16:03 UTC

Hi Juerd,
0**0 should be somewhere between 0 and undefined (source: here).
So, actually, it should return undef, since that's what most (if not all) mathbooks say.
Hope it helps,
Greets,
 JaWi
"A chicken is an egg's way of producing more eggs."  [reply] [d/l] 

I disagree. Yes, there are situations where 0^0 should be undefined, but there are also several cases where it should be 1. Given that, I don't want my numerical methods package to be crashing all the time because Perl thinks it should be undef.
The fact is, the coder should know which case he is interested in (1 or undef as the answer); I think it is better from a coding perspective to check for the undef case, and just allow the 0^0 == 1 case without special checking.
Now, who the heck is writing numerical methods packages in PerlFORTRAN is the way to go :)
Scott
Project coordinator of the Generic Model Organism Database Project
 [reply] 

 [reply] [d/l] 


Re: 0**0
by toma (Vicar) on Jan 18, 2003 at 05:25 UTC

Perhaps this is why engineers want 0**0 = 1
foreach my $close_to_zero (1e3,
1e4,
1e5,
1e6,
1e7,
1e8,
1e9,
1e10,
1e11,
1e12,
1e13,
){
print $close_to_zero**$close_to_zero,"\n";
}
produces
0.993116048420934
0.999079389984462
0.999884877372469
0.999986184584876
0.999998388191734
0.99999981579321
0.999999979276734
0.999999997697415
0.999999999746716
0.999999999972369
0.999999999997007
If you approach zero from the negative side,
it doesn't work. There are many other directions
you can approach from, using complex numbers.
From these directions the answer also seems
to head toward a limit of 1.
use Math::Complex;
my $j=sqrt(1)/100;
foreach my $close_to_zero (1e3$j*1e3,
1e4$j*1e4,
1e5$j*1e5,
1e6$j*1e6,
1e7$j*1e7,
1e8$j*1e8,
1e9$j*1e9,
1e10$j*1e10,
1e11$j*1e11,
1e12$j*1e12,
1e13$j*1e13,
){
print $close_to_zero**$close_to_zero,"\n";
}
prints
1.00689492851834+0.00322274943578533i
1.00091826683245+0.000322665621543586i
1.00011482165982+3.24709453669811e05i
1.00001378423429+3.2697926634863e06i
1.00000160867421+3.29277874043755e07i
1.00000018389316+3.31579990412048e08i
1.0000000206919+3.33882521438423e09i
1.00000000229945+3.36185100395793e10i
1.00000000025297+3.38487684801375e11i
1.0000000000276+3.40790269818147e12i
1.00000000000299+3.43092854902761e13i
So my engineering view is that 0**0==1
most of the time, for large values of zero.
It should work perfectly the first time!  toma  [reply] [d/l] [select] 
Re: 0**0
by osama (Scribe) on Jan 17, 2003 at 10:35 UTC

I thought that anything**0=1, even if it's 0**0, it's actually very logical.
Maybe engineers prefer 0**0=1, mathematicians prefer undef!
 [reply] 

 [reply] [d/l] [select] 