# New Ticket Created by [EMAIL PROTECTED] # Please include the string: [perl #37117] # in the subject line of all future correspondence about this issue. # <URL: https://rt.perl.org/rt3/Ticket/Display.html?id=37117 >
This is a bug report for perl from [EMAIL PROTECTED], generated with the help of perlbug 1.35 running under perl v5.8.7. This bug is still present in 5.9.2. ----------------------------------------------------------------- [I just found out about perlbug. I hope this finally is the preferred method of reporting bugs. This one's really easy to fix (just apply the three line patch), but can be a real hassle if it isn't fixed. I have tried contacting the former module author (before Math::Complex went into the core), but the mail address of Mr. Lewart is no longer valid.] The syntax of using the atan2 routine is, generally: atan2(y, x) = atan(y/x). You will know that atan(0) = 0. (Since tan(0) = 0 = sin(0) / cos(0).) perl -MMath::Complex -e "print atan2(0,1)" prints '0' alright. (Which is, in fact atan(0/1).) perl -MMath::Complex -e "print atan2(1,0)" prints pi/2 alright. (Which is, in fact atan(1/0) and lim(x-->inf) atan(x) is pi/2.) Now, in the complex plane, we get: perl -MMath::Complex -e "print atan2(0,i)" i/0: Division by zero. Died at c:/perl/perl58/lib/Math/Complex.pm line 1284. This is not correct. Obviously, 0/i is the same as 0/1 which is 0. Thus atan2(0,i) == atan2(0,1) == atan(0) == 0 At fault is the following code: sub atan2 { my ($z1, $z2, $inverted) = [at]_; my ($re1, $im1, $re2, $im2); if ($inverted) { ($re1, $im1) = ref $z2 ? [at]{$z2->cartesian} : ($z2, 0); ($re2, $im2) = [at]{$z1->cartesian}; } else { ($re1, $im1) = [at]{$z1->cartesian}; ($re2, $im2) = ref $z2 ? [at]{$z2->cartesian} : ($z2, 0); } if ($im2 == 0) { return CORE::atan2($re1, $re2) if $im1 == 0; return ($im1<=>0) * pip2 if $re2 == 0; } my $w = atan($z1/$z2); # !!! line 1284 my ($u, $v) = ref $w ? [at]{$w->cartesian} : ($w, 0); $u += pi if $re2 < 0; $u -= pit2 if $u > pi; return cplx($u, $v); } In the last test case above, $inverted is set. Therefore, if $im2 = 0, the switched real and imaginary parts are used. But if that's not the case, the code at line 1284 is executed with the *unswitched* complex numbers $z1 and $z2. I suppose the author omitted something like ($z1, $z2) = ($z2, $z1) if $inverted; before line 1284. (The patch uses slightly different code.) I attached a patch which adds another if($inverted){}else{} block. It's a patch against the Math::Complex in 5.8.7, but I have verified that the version in the bleadperl is the same. I assume you want to add a test for any bugfix, but since I know nothing about perl's internal testing (and Complex.t in 5.9.2 is as ugly as it gets), I'll just include the simplest bit of code that tests the patch, provided Math::Complex was loaded: ($eps defined in Complex.t) my $res; eval {$res = atan2(0,i);}; print( ($@ or not abs($res) < $eps ) ? 'not ok' : 'ok' ); diff -u follows: ----- --- Complex.pm 2005-04-01 11:43:02.000000000 +0200 +++ C:/perl/perl58/lib/Math/Complex.pm 2005-08-04 16:45:13.890625000 +0200 @@ -1281,7 +1281,13 @@ return CORE::atan2($re1, $re2) if $im1 == 0; return ($im1<=>0) * pip2 if $re2 == 0; } - my $w = atan($z1/$z2); + my $w; + if ($inverted) { + $w = atan($z2/$z1); + } + else { + $w = atan($z1/$z2); + } my ($u, $v) = ref $w ? @{$w->cartesian} : ($w, 0); $u += pi if $re2 < 0; $u -= pit2 if $u > pi; ----- Steffen Mueller ----------------------------------------------------------------- --- Flags: category=core severity=medium --- Site configuration information for perl v5.8.7: Configured by builder at Mon Jun 6 13:36:05 2005. Summary of my perl5 (revision 5 version 8 subversion 7) configuration: Platform: osname=MSWin32, osvers=5.0, archname=MSWin32-x86-multi-thread uname='' config_args='undef' hint=recommended, useposix=true, d_sigaction=undef usethreads=define use5005threads=undef useithreads=define usemultiplicity=define useperlio=define d_sfio=undef uselargefiles=define usesocks=undef use64bitint=undef use64bitall=undef uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='cl', ccflags ='-nologo -Gf -W3 -MD -Zi -DNDEBUG -O1 -DWIN32 -D_CONSOLE -DNO_STRICT -DHAVE_DES_FCRYPT -DBUILT_BY_ACTIVESTATE -DNO_HASH_SEED -DUSE_SITECUSTOMIZE -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -DUSE_PERLIO -DPERL_MSVCRT_READFIX', optimize='-MD -Zi -DNDEBUG -O1', cppflags='-DWIN32' ccversion='12.00.8804', gccversion='', gccosandvers='' intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234 d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=10 ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='__int64', lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='link', ldflags ='-nologo -nodefaultlib -debug -opt:ref,icf -libpath:"c:\perl\perl58\lib\CORE" -machine:x86' libpth=\lib libs= oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib msvcrt.lib perllibs= oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib msvcrt.lib libc=msvcrt.lib, so=dll, useshrplib=yes, libperl=perl58.lib gnulibc_version='undef' Dynamic Linking: dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' ' cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -debug -opt:ref,icf -libpath:"c:\perl\perl58\lib\CORE" -machine:x86' Locally applied patches: ACTIVEPERL_LOCAL_PATCHES_ENTRY # if !defined(PERL_DARWIN) Iin_load_module moved for compatibility with build 806 # endif # if defined(__hpux) Avoid signal flag SA_RESTART for older versions of HP-UX # endif PerlEx hacks for CGI::Carp Less verbose ExtUtils::Install and Pod::Find instmodsh upgraded from ExtUtils-MakeMaker-6.25 24699 ICMP_UNREACHABLE handling in Net::Ping 21540 Fix backward-compatibility issues in if.pm --- @INC for perl v5.8.7: c:/perl/perl58/lib c:/perl/perl58/site/lib . --- Environment for perl v5.8.7: HOME (unset) LANG (unset) LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=D:\texmf\miktex\bin;c:\perl\perl58\bin;C:\cygwin\bin;C:\Tcl\bin;p:\util;p:\util\gnuplot\bin;p:\util\perltidy\bin;C:\WINNT\system32;C:\WINNT;C:\WINNT\system32\nls;C:\WINNT\system32\nls\ENGLISH;C:\Programme\Network Associates\PGPNT;C:\Programme\Novell\ZENworks\;C:\Programme\Gemeinsame Dateien\GTK\2.0\bin;p:\sdbdata;p:\sdbdata\sdbdata_win;c:\cygwin\usr\X11R6\bin PERL_BADLANG (unset) SHELL (unset)