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 Abigail-II (Bishop) on Jan 16, 2003 at 16:40 UTC
|
# uname -srvm
HP-UX 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] |
|
This is perl, version 4.0
Thanks, but my code won't run with Perl 4 anyway. Have you got Perl 5 installed on that box? If it doesn't work, I'll have to avoid using 0**0 in my code.
Juerd
- http://juerd.nl/
- spamcollector_perlmonks@juerd.nl (do not use).
| [reply] |
|
jkruck:<rue> % uname -srvm
HP-UX B.11.00 U 9000/800
jkruck:<rue> % perl -v
This is perl, version 5.005_03 built for PA-RISC1.1
Copyright 1987-1999, 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 en = -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 perl-5.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 power-of-2 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 x-value 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) math-books 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 Perl--FORTRAN 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 (1e-3,
1e-4,
1e-5,
1e-6,
1e-7,
1e-8,
1e-9,
1e-10,
1e-11,
1e-12,
1e-13,
){
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 (-1e-3-$j*1e-3,
-1e-4-$j*1e-4,
-1e-5-$j*1e-5,
-1e-6-$j*1e-6,
-1e-7-$j*1e-7,
-1e-8-$j*1e-8,
-1e-9-$j*1e-9,
-1e-10-$j*1e-10,
-1e-11-$j*1e-11,
-1e-12-$j*1e-12,
-1e-13-$j*1e-13,
){
print $close_to_zero**$close_to_zero,"\n";
}
prints
1.00689492851834+0.00322274943578533i
1.00091826683245+0.000322665621543586i
1.00011482165982+3.24709453669811e-05i
1.00001378423429+3.2697926634863e-06i
1.00000160867421+3.29277874043755e-07i
1.00000018389316+3.31579990412048e-08i
1.0000000206919+3.33882521438423e-09i
1.00000000229945+3.36185100395793e-10i
1.00000000025297+3.38487684801375e-11i
1.0000000000276+3.40790269818147e-12i
1.00000000000299+3.43092854902761e-13i
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] |