summaryrefslogtreecommitdiffstats
path: root/contrib/perl5/lib/Math
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/perl5/lib/Math')
-rw-r--r--contrib/perl5/lib/Math/BigFloat.pm57
-rw-r--r--contrib/perl5/lib/Math/BigInt.pm89
-rw-r--r--contrib/perl5/lib/Math/Complex.pm188
-rw-r--r--contrib/perl5/lib/Math/Trig.pm32
4 files changed, 278 insertions, 88 deletions
diff --git a/contrib/perl5/lib/Math/BigFloat.pm b/contrib/perl5/lib/Math/BigFloat.pm
index 03bc2f4..d8d643c 100644
--- a/contrib/perl5/lib/Math/BigFloat.pm
+++ b/contrib/perl5/lib/Math/BigFloat.pm
@@ -9,10 +9,8 @@ use overload
'+' => sub {new Math::BigFloat &fadd},
'-' => sub {new Math::BigFloat
$_[2]? fsub($_[1],${$_[0]}) : fsub(${$_[0]},$_[1])},
-'<=>' => sub {new Math::BigFloat
- $_[2]? fcmp($_[1],${$_[0]}) : fcmp(${$_[0]},$_[1])},
-'cmp' => sub {new Math::BigFloat
- $_[2]? ($_[1] cmp ${$_[0]}) : (${$_[0]} cmp $_[1])},
+'<=>' => sub {$_[2]? fcmp($_[1],${$_[0]}) : fcmp(${$_[0]},$_[1])},
+'cmp' => sub {$_[2]? ($_[1] cmp ${$_[0]}) : (${$_[0]} cmp $_[1])},
'*' => sub {new Math::BigFloat &fmul},
'/' => sub {new Math::BigFloat
$_[2]? scalar fdiv($_[1],${$_[0]}) :
@@ -28,9 +26,9 @@ qw(
sub new {
my ($class) = shift;
my ($foo) = fnorm(shift);
- panic("Not a number initialized to Math::BigFloat") if $foo eq "NaN";
bless \$foo, $class;
}
+
sub numify { 0 + "${$_[0]}" } # Not needed, additional overhead
# comparing to direct compilation based on
# stringify
@@ -76,6 +74,7 @@ sub fnorm; sub fsqrt;
sub fnorm { #(string) return fnum_str
local($_) = @_;
s/\s+//g; # strip white space
+ no warnings; # $4 and $5 below might legitimately be undefined
if (/^([+-]?)(\d*)(\.(\d*))?([Ee]([+-]?\d+))?$/ && "$2$4" ne '') {
&norm(($1 ? "$1$2$4" : "+$2$4"),(($4 ne '') ? $6-length($4) : $6));
} else {
@@ -159,7 +158,8 @@ sub fdiv #(fnum_str, fnum_str[,scale]) return fnum_str
$scale = length($xm)-1 if (length($xm)-1 > $scale);
$scale = length($ym)-1 if (length($ym)-1 > $scale);
$scale = $scale + length($ym) - length($xm);
- &norm(&round(Math::BigInt::bdiv($xm.('0' x $scale),$ym),$ym),
+ &norm(&round(Math::BigInt::bdiv($xm.('0' x $scale),$ym),
+ Math::BigInt::babs($ym)),
$xe-$ye-$scale);
}
}
@@ -219,7 +219,11 @@ sub ffround { #(fnum_str, scale) return fnum_str
if ($xe < 1) {
'+0E+0';
} elsif ($xe == 1) {
- &norm(&round('+0',"+0".substr($xm,$[+1,1),"+10"), $scale);
+ # The first substr preserves the sign, passing a non-
+ # normalized "-0" to &round when rounding -0.006 (for
+ # example), purely so &round won't lose the sign.
+ &norm(&round(substr($xm,$[,1).'0',
+ "+0".substr($xm,$[+1,1),"+10"), $scale);
} else {
&norm(&round(substr($xm,$[,$xe),
"+0".substr($xm,$[+$xe,1),"+10"), $scale);
@@ -236,12 +240,13 @@ sub fcmp #(fnum_str, fnum_str) return cond_code
if ($x eq "NaN" || $y eq "NaN") {
undef;
} else {
+ local($xm,$xe,$ym,$ye) = split('E', $x."E$y");
+ if ($xm eq '+0' || $ym eq '+0') {
+ return $xm <=> $ym;
+ }
ord($y) <=> ord($x)
- ||
- ( local($xm,$xe,$ym,$ye) = split('E', $x."E$y"),
- (($xe <=> $ye) * (substr($x,$[,1).'1')
- || Math::BigInt::cmp($xm,$ym))
- );
+ || ($xe <=> $ye) * (substr($x,$[,1).'1')
+ || Math::BigInt::cmp($xm,$ym);
}
}
@@ -301,7 +306,7 @@ floats as
=item number format
canonical strings have the form /[+-]\d+E[+-]\d+/ . Input values can
-have imbedded whitespace.
+have embedded whitespace.
=item Error returns 'NaN'
@@ -310,9 +315,24 @@ negative number.
=item Division is computed to
-C<max($div_scale,length(dividend)+length(divisor))> digits by default.
+C<max($Math::BigFloat::div_scale,length(dividend)+length(divisor))>
+digits by default.
Also used for default sqrt scale.
+=item Rounding is performed
+
+according to the value of
+C<$Math::BigFloat::rnd_mode>:
+
+ trunc truncate the value
+ zero round towards 0
+ +inf round towards +infinity (round up)
+ -inf round towards -infinity (round down)
+ even round to the nearest, .5 to the even digit
+ odd round to the nearest, .5 to the odd digit
+
+The default is C<even> rounding.
+
=back
=head1 BUGS
@@ -320,6 +340,15 @@ Also used for default sqrt scale.
The current version of this module is a preliminary version of the
real thing that is currently (as of perl5.002) under development.
+The printf subroutine does not use the value of
+C<$Math::BigFloat::rnd_mode> when rounding values for printing.
+Consequently, the way to print rounded values is
+to specify the number of digits both as an
+argument to C<ffround> and in the C<%f> printf string,
+as follows:
+
+ printf "%.3f\n", $bigfloat->ffround(-3);
+
=head1 AUTHOR
Mark Biggar
diff --git a/contrib/perl5/lib/Math/BigInt.pm b/contrib/perl5/lib/Math/BigInt.pm
index b61b884..a43969c 100644
--- a/contrib/perl5/lib/Math/BigInt.pm
+++ b/contrib/perl5/lib/Math/BigInt.pm
@@ -4,10 +4,8 @@ use overload
'+' => sub {new Math::BigInt &badd},
'-' => sub {new Math::BigInt
$_[2]? bsub($_[1],${$_[0]}) : bsub(${$_[0]},$_[1])},
-'<=>' => sub {new Math::BigInt
- $_[2]? bcmp($_[1],${$_[0]}) : bcmp(${$_[0]},$_[1])},
-'cmp' => sub {new Math::BigInt
- $_[2]? ($_[1] cmp ${$_[0]}) : (${$_[0]} cmp $_[1])},
+'<=>' => sub {$_[2]? bcmp($_[1],${$_[0]}) : bcmp(${$_[0]},$_[1])},
+'cmp' => sub {$_[2]? ($_[1] cmp ${$_[0]}) : (${$_[0]} cmp $_[1])},
'*' => sub {new Math::BigInt &bmul},
'/' => sub {new Math::BigInt
$_[2]? scalar bdiv($_[1],${$_[0]}) :
@@ -18,6 +16,14 @@ use overload
$_[2]? bpow($_[1],${$_[0]}) : bpow(${$_[0]},$_[1])},
'neg' => sub {new Math::BigInt &bneg},
'abs' => sub {new Math::BigInt &babs},
+'<<' => sub {new Math::BigInt
+ $_[2]? blsft($_[1],${$_[0]}) : blsft(${$_[0]},$_[1])},
+'>>' => sub {new Math::BigInt
+ $_[2]? brsft($_[1],${$_[0]}) : brsft(${$_[0]},$_[1])},
+'&' => sub {new Math::BigInt &band},
+'|' => sub {new Math::BigInt &bior},
+'^' => sub {new Math::BigInt &bxor},
+'~' => sub {new Math::BigInt &bnot},
qw(
"" stringify
@@ -258,9 +264,11 @@ sub bdiv { #(dividend: num_str, divisor: num_str) return num_str
else {
push(@x, 0);
}
- @q = (); ($v2,$v1) = ($y[-2] || 0, $y[-1]);
+ @q = (); ($v2,$v1) = @y[-2,-1];
+ $v2 = 0 unless $v2;
while ($#x > $#y) {
- ($u2,$u1,$u0) = ($x[-3] || 0, $x[-2] || 0, $x[-1]);
+ ($u2,$u1,$u0) = @x[-3..-1];
+ $u2 = 0 unless $u2;
$q = (($u0 == $v1) ? 99999 : int(($u0*1e5+$u1)/$v1));
--$q while ($v2*$q > ($u0*1e5+$u1-$q*$v1)*1e5+$u2);
if ($q) {
@@ -328,6 +336,69 @@ sub bpow { #(num_str, num_str) return num_str
}
}
+# compute x << y, y >= 0
+sub blsft { #(num_str, num_str) return num_str
+ &bmul($_[$[], &bpow(2, $_[$[+1]));
+}
+
+# compute x >> y, y >= 0
+sub brsft { #(num_str, num_str) return num_str
+ &bdiv($_[$[], &bpow(2, $_[$[+1]));
+}
+
+# compute x & y
+sub band { #(num_str, num_str) return num_str
+ local($x,$y,$r,$m,$xr,$yr) = (&bnorm($_[$[]),&bnorm($_[$[+1]),0,1);
+ if ($x eq 'NaN' || $y eq 'NaN') {
+ 'NaN';
+ } else {
+ while ($x ne '+0' && $y ne '+0') {
+ ($x, $xr) = &bdiv($x, 0x10000);
+ ($y, $yr) = &bdiv($y, 0x10000);
+ $r = &badd(&bmul(int $xr & $yr, $m), $r);
+ $m = &bmul($m, 0x10000);
+ }
+ $r;
+ }
+}
+
+# compute x | y
+sub bior { #(num_str, num_str) return num_str
+ local($x,$y,$r,$m,$xr,$yr) = (&bnorm($_[$[]),&bnorm($_[$[+1]),0,1);
+ if ($x eq 'NaN' || $y eq 'NaN') {
+ 'NaN';
+ } else {
+ while ($x ne '+0' || $y ne '+0') {
+ ($x, $xr) = &bdiv($x, 0x10000);
+ ($y, $yr) = &bdiv($y, 0x10000);
+ $r = &badd(&bmul(int $xr | $yr, $m), $r);
+ $m = &bmul($m, 0x10000);
+ }
+ $r;
+ }
+}
+
+# compute x ^ y
+sub bxor { #(num_str, num_str) return num_str
+ local($x,$y,$r,$m,$xr,$yr) = (&bnorm($_[$[]),&bnorm($_[$[+1]),0,1);
+ if ($x eq 'NaN' || $y eq 'NaN') {
+ 'NaN';
+ } else {
+ while ($x ne '+0' || $y ne '+0') {
+ ($x, $xr) = &bdiv($x, 0x10000);
+ ($y, $yr) = &bdiv($y, 0x10000);
+ $r = &badd(&bmul(int $xr ^ $yr, $m), $r);
+ $m = &bmul($m, 0x10000);
+ }
+ $r;
+ }
+}
+
+# represent ~x as twos-complement number
+sub bnot { #(num_str) return num_str
+ &bsub(-1,$_[$[]);
+}
+
1;
__END__
@@ -350,6 +421,12 @@ Math::BigInt - Arbitrary size integer math package
$i->bmod(BINT) return BINT modulus
$i->bgcd(BINT) return BINT greatest common divisor
$i->bnorm return BINT normalization
+ $i->blsft(BINT) return BINT left shift
+ $i->brsft(BINT) return (BINT,BINT) right shift (quo,rem) just quo if scalar
+ $i->band(BINT) return BINT bit-wise and
+ $i->bior(BINT) return BINT bit-wise inclusive or
+ $i->bxor(BINT) return BINT bit-wise exclusive or
+ $i->bnot return BINT bit-wise not
=head1 DESCRIPTION
diff --git a/contrib/perl5/lib/Math/Complex.pm b/contrib/perl5/lib/Math/Complex.pm
index 5b69039..1a47f4a 100644
--- a/contrib/perl5/lib/Math/Complex.pm
+++ b/contrib/perl5/lib/Math/Complex.pm
@@ -8,9 +8,10 @@
require Exporter;
package Math::Complex;
+use 5.005_64;
use strict;
-use vars qw($VERSION @ISA @EXPORT %EXPORT_TAGS);
+our($VERSION, @ISA, @EXPORT, %EXPORT_TAGS);
my ( $i, $ip2, %logn );
@@ -65,9 +66,10 @@ use overload
# Package "privates"
#
-my $package = 'Math::Complex'; # Package name
-my $display = 'cartesian'; # Default display format
-my $eps = 1e-14; # Epsilon
+my $package = 'Math::Complex'; # Package name
+my %DISPLAY_FORMAT = ('style' => 'cartesian',
+ 'polar_pretty_print' => 1);
+my $eps = 1e-14; # Epsilon
#
# Object attributes (internal):
@@ -160,7 +162,7 @@ sub new { &make } # For backward compatibility only.
#
sub cplx {
my ($re, $im) = @_;
- return $package->make($re, defined $im ? $im : 0);
+ return __PACKAGE__->make($re, defined $im ? $im : 0);
}
#
@@ -171,7 +173,7 @@ sub cplx {
#
sub cplxe {
my ($rho, $theta) = @_;
- return $package->emake($rho, defined $theta ? $theta : 0);
+ return __PACKAGE__->emake($rho, defined $theta ? $theta : 0);
}
#
@@ -179,21 +181,21 @@ sub cplxe {
#
# The number defined as pi = 180 degrees
#
-use constant pi => 4 * CORE::atan2(1, 1);
+sub pi () { 4 * CORE::atan2(1, 1) }
#
# pit2
#
# The full circle
#
-use constant pit2 => 2 * pi;
+sub pit2 () { 2 * pi }
#
# pip2
#
# The quarter circle
#
-use constant pip2 => pi / 2;
+sub pip2 () { pi / 2 }
#
# deg1
@@ -201,14 +203,14 @@ use constant pip2 => pi / 2;
# One degree in radians, used in stringify_polar.
#
-use constant deg1 => pi / 180;
+sub deg1 () { pi / 180 }
#
# uplog10
#
# Used in log10().
#
-use constant uplog10 => 1 / CORE::log(10);
+sub uplog10 () { 1 / CORE::log(10) }
#
# i
@@ -835,7 +837,7 @@ sub acos {
my $u = CORE::atan2(CORE::sqrt(1-$beta*$beta), $beta);
my $v = CORE::log($alpha + CORE::sqrt($alpha*$alpha-1));
$v = -$v if $y > 0 || ($y == 0 && $x < -1);
- return $package->make($u, $v);
+ return __PACKAGE__->make($u, $v);
}
#
@@ -857,7 +859,7 @@ sub asin {
my $u = CORE::atan2($beta, CORE::sqrt(1-$beta*$beta));
my $v = -CORE::log($alpha + CORE::sqrt($alpha*$alpha-1));
$v = -$v if $y > 0 || ($y == 0 && $x < -1);
- return $package->make($u, $v);
+ return __PACKAGE__->make($u, $v);
}
#
@@ -1153,34 +1155,53 @@ sub atan2 {
# display_format
# ->display_format
#
-# Set (fetch if no argument) display format for all complex numbers that
+# Set (get if no argument) the display format for all complex numbers that
# don't happen to have overridden it via ->display_format
#
-# When called as a method, this actually sets the display format for
+# When called as an object method, this actually sets the display format for
# the current object.
#
# Valid object formats are 'c' and 'p' for cartesian and polar. The first
# letter is used actually, so the type can be fully spelled out for clarity.
#
sub display_format {
- my $self = shift;
- my $format = undef;
+ my $self = shift;
+ my %display_format = %DISPLAY_FORMAT;
- if (ref $self) { # Called as a method
- $format = shift;
- } else { # Regular procedure call
- $format = $self;
- undef $self;
+ if (ref $self) { # Called as an object method
+ if (exists $self->{display_format}) {
+ my %obj = %{$self->{display_format}};
+ @display_format{keys %obj} = values %obj;
+ }
+ if (@_ == 1) {
+ $display_format{style} = shift;
+ } else {
+ my %new = @_;
+ @display_format{keys %new} = values %new;
+ }
+ } else { # Called as a class method
+ if (@_ = 1) {
+ $display_format{style} = $self;
+ } else {
+ my %new = @_;
+ @display_format{keys %new} = values %new;
+ }
+ undef $self;
}
if (defined $self) {
- return defined $self->{display} ? $self->{display} : $display
- unless defined $format;
- return $self->{display} = $format;
+ $self->{display_format} = { %display_format };
+ return
+ wantarray ?
+ %{$self->{display_format}} :
+ $self->{display_format}->{style};
}
- return $display unless defined $format;
- return $display = $format;
+ %DISPLAY_FORMAT = %display_format;
+ return
+ wantarray ?
+ %DISPLAY_FORMAT :
+ $DISPLAY_FORMAT{style};
}
#
@@ -1195,12 +1216,12 @@ sub display_format {
#
sub stringify {
my ($z) = shift;
- my $format;
- $format = $display;
- $format = $z->{display} if defined $z->{display};
+ my $style = $z->display_format;
+
+ $style = $DISPLAY_FORMAT{style} unless defined $style;
- return $z->stringify_polar if $format =~ /^p/i;
+ return $z->stringify_polar if $style =~ /^p/i;
return $z->stringify_cartesian;
}
@@ -1220,17 +1241,27 @@ sub stringify_cartesian {
if int(CORE::abs($y)) != int(CORE::abs($y) + $eps);
$re = "$x" if CORE::abs($x) >= $eps;
- if ($y == 1) { $im = 'i' }
- elsif ($y == -1) { $im = '-i' }
- elsif (CORE::abs($y) >= $eps) { $im = $y . "i" }
+
+ my %format = $z->display_format;
+ my $format = $format{format};
+
+ if ($y == 1) { $im = 'i' }
+ elsif ($y == -1) { $im = '-i' }
+ elsif (CORE::abs($y) >= $eps) {
+ $im = (defined $format ? sprintf($format, $y) : $y) . "i";
+ }
my $str = '';
- $str = $re if defined $re;
- $str .= "+$im" if defined $im;
- $str =~ s/\+-/-/;
- $str =~ s/^\+//;
- $str =~ s/([-+])1i/$1i/; # Not redundant with the above 1/-1 tests.
- $str = '0' unless $str;
+ $str = defined $format ? sprintf($format, $re) : $re
+ if defined $re;
+ if (defined $im) {
+ if ($y < 0) {
+ $str .= $im;
+ } elsif ($y > 0) {
+ $str .= "+" if defined $re;
+ $str .= $im;
+ }
+ }
return $str;
}
@@ -1277,6 +1308,8 @@ sub stringify_polar {
return '[0,0]' if $r <= $eps;
+ my %format = $z->display_format;
+
my $nt = $t / pit2;
$nt = ($nt - int($nt)) * pit2;
$nt += pit2 if $nt < 0; # Range [0, 2pi]
@@ -1299,7 +1332,7 @@ sub stringify_polar {
$nt -= pit2 if $nt > pi;
- if (CORE::abs($nt) >= deg1) {
+ if ($format{polar_pretty_print} && CORE::abs($nt) >= deg1) {
my ($n, $k, $kpi);
for ($k = 1, $kpi = pi; $k < 10; $k++, $kpi += pi) {
@@ -1328,12 +1361,19 @@ sub stringify_polar {
if ($theta !~ m(^-?\d*pi/\d+$) and
int(CORE::abs($theta)) != int(CORE::abs($theta) + $eps));
+ my $format = $format{format};
+ if (defined $format) {
+ $r = sprintf($format, $r);
+ $theta = sprintf($format, $theta);
+ }
+
return "\[$r,$theta\]";
}
1;
__END__
+=pod
=head1 NAME
Math::Complex - complex numbers and associated mathematical functions
@@ -1617,9 +1657,9 @@ It is possible to write:
$x = cplxe(-3, pi/4);
-but that will be silently converted into C<[3,-3pi/4]>, since the modulus
-must be non-negative (it represents the distance to the origin in the complex
-plane).
+but that will be silently converted into C<[3,-3pi/4]>, since the
+modulus must be non-negative (it represents the distance to the origin
+in the complex plane).
It is also possible to have a complex number as either argument of
either the C<make> or C<emake>: the appropriate component of
@@ -1631,31 +1671,67 @@ the argument will be used.
=head1 STRINGIFICATION
When printed, a complex number is usually shown under its cartesian
-form I<a+bi>, but there are legitimate cases where the polar format
+style I<a+bi>, but there are legitimate cases where the polar style
I<[r,t]> is more appropriate.
-By calling the routine C<Math::Complex::display_format> and supplying either
-C<"polar"> or C<"cartesian">, you override the default display format,
-which is C<"cartesian">. Not supplying any argument returns the current
-setting.
+By calling the class method C<Math::Complex::display_format> and
+supplying either C<"polar"> or C<"cartesian"> as an argument, you
+override the default display style, which is C<"cartesian">. Not
+supplying any argument returns the current settings.
This default can be overridden on a per-number basis by calling the
C<display_format> method instead. As before, not supplying any argument
-returns the current display format for this number. Otherwise whatever you
-specify will be the new display format for I<this> particular number.
+returns the current display style for this number. Otherwise whatever you
+specify will be the new display style for I<this> particular number.
For instance:
use Math::Complex;
Math::Complex::display_format('polar');
- $j = ((root(1, 3))[1];
- print "j = $j\n"; # Prints "j = [1,2pi/3]
+ $j = (root(1, 3))[1];
+ print "j = $j\n"; # Prints "j = [1,2pi/3]"
$j->display_format('cartesian');
print "j = $j\n"; # Prints "j = -0.5+0.866025403784439i"
-The polar format attempts to emphasize arguments like I<k*pi/n>
-(where I<n> is a positive integer and I<k> an integer within [-9,+9]).
+The polar style attempts to emphasize arguments like I<k*pi/n>
+(where I<n> is a positive integer and I<k> an integer within [-9,+9]),
+this is called I<polar pretty-printing>.
+
+=head2 CHANGED IN PERL 5.6
+
+The C<display_format> class method and the corresponding
+C<display_format> object method can now be called using
+a parameter hash instead of just a one parameter.
+
+The old display format style, which can have values C<"cartesian"> or
+C<"polar">, can be changed using the C<"style"> parameter. (The one
+parameter calling convention also still works.)
+
+There are two new display parameters.
+
+The first one is C<"format">, which is a sprintf()-style format
+string to be used for both parts of the complex number(s). The
+default is C<undef>, which corresponds usually (this is somewhat
+system-dependent) to C<"%.15g">. You can revert to the default by
+setting the format string to C<undef>.
+
+ # the $j from the above example
+
+ $j->display_format('format' => '%.5f');
+ print "j = $j\n"; # Prints "j = -0.50000+0.86603i"
+ $j->display_format('format' => '%.6f');
+ print "j = $j\n"; # Prints "j = -0.5+0.86603i"
+
+Notice that this affects also the return values of the
+C<display_format> methods: in list context the whole parameter hash
+will be returned, as opposed to only the style parameter value. If
+you want to know the whole truth for a complex number, you must call
+both the class method and the object method:
+
+The second new display parameter is C<"polar_pretty_print">, which can
+be set to true or false, the default being true. See the previous
+section for what this means.
=head1 USAGE
@@ -1746,7 +1822,7 @@ Whatever it is, it does not manifest itself anywhere else where Perl runs.
=head1 AUTHORS
-Raphael Manfredi <F<Raphael_Manfredi@grenoble.hp.com>> and
+Raphael Manfredi <F<Raphael_Manfredi@pobox.com>> and
Jarkko Hietaniemi <F<jhi@iki.fi>>.
Extensive patches by Daniel S. Lewart <F<d-lewart@uiuc.edu>>.
diff --git a/contrib/perl5/lib/Math/Trig.pm b/contrib/perl5/lib/Math/Trig.pm
index 924286d..492706c 100644
--- a/contrib/perl5/lib/Math/Trig.pm
+++ b/contrib/perl5/lib/Math/Trig.pm
@@ -7,13 +7,12 @@
require Exporter;
package Math::Trig;
+use 5.005_64;
use strict;
use Math::Complex qw(:trig);
-use vars qw($VERSION $PACKAGE
- @ISA
- @EXPORT @EXPORT_OK %EXPORT_TAGS);
+our($VERSION, $PACKAGE, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
@ISA = qw(Exporter);
@@ -37,8 +36,8 @@ my @rdlcnv = qw(cartesian_to_cylindrical
%EXPORT_TAGS = ('radial' => [ @rdlcnv ]);
-use constant pi2 => 2 * pi;
-use constant pip2 => pi / 2;
+sub pi2 () { 2 * pi } # use constant generates warning
+sub pip2 () { pi / 2 } # use constant generates warning
use constant DR => pi2/360;
use constant RD => 360/pi2;
use constant DG => 400/360;
@@ -133,11 +132,11 @@ Math::Trig - trigonometric functions
=head1 SYNOPSIS
use Math::Trig;
-
+
$x = tan(0.9);
$y = acos(3.7);
$z = asin(2.4);
-
+
$halfpi = pi/2;
$rad = deg2rad(120);
@@ -259,7 +258,7 @@ complex numbers as results because the C<Math::Complex> takes care of
details like for example how to display complex numbers. For example:
print asin(2), "\n";
-
+
should produce something like this (take or leave few last decimals):
1.5707963267949-1.31695789692482i
@@ -273,10 +272,10 @@ and the imaginary part of approximately C<-1.317>.
$radians = deg2rad($degrees);
$radians = grad2rad($gradians);
-
+
$degrees = rad2deg($radians);
$degrees = grad2deg($gradians);
-
+
$gradians = deg2grad($degrees);
$gradians = rad2grad($radians);
@@ -409,7 +408,16 @@ To calculate the distance between London (51.3N 0.5W) and Tokyo (35.7N
$km = great_circle_distance(@L, @T, 6378);
The answer may be off by few percentages because of the irregular
-(slightly aspherical) form of the Earth.
+(slightly aspherical) form of the Earth. The used formula
+
+ lat0 = 90 degrees - phi0
+ lat1 = 90 degrees - phi1
+ d = R * arccos(cos(lat0) * cos(lat1) * cos(lon1 - lon01) +
+ sin(lat0) * sin(lat1))
+
+is also somewhat unreliable for small distances (for locations
+separated less than about five degrees) because it uses arc cosine
+which is rather ill-conditioned for values close to zero.
=head1 BUGS
@@ -426,7 +434,7 @@ an answer instead of giving a fatal runtime error.
=head1 AUTHORS
Jarkko Hietaniemi <F<jhi@iki.fi>> and
-Raphael Manfredi <F<Raphael_Manfredi@grenoble.hp.com>>.
+Raphael Manfredi <F<Raphael_Manfredi@pobox.com>>.
=cut
OpenPOWER on IntegriCloud