diff options
author | Andy Dougherty <doughera@lafcol.lafayette.edu> | 1996-02-28 16:49:33 -0800 |
---|---|---|
committer | Andy Dougherty <doughera@lafcol.lafayette.edu> | 1996-02-28 16:49:33 -0800 |
commit | a5f75d667838e8e7bb037880391f5c44476d33b4 (patch) | |
tree | 5005e888355c1508bc47da697efe119c1615b123 /lib/Math | |
parent | 2920c5d2b358b11ace52104b6944bfa0e89256a7 (diff) | |
download | perl-a5f75d667838e8e7bb037880391f5c44476d33b4.tar.gz |
perl 5.002perl-5.002
[editor's note: changes seem to be mostly module updates,
documentation changes and some perl API macro additions]
Diffstat (limited to 'lib/Math')
-rw-r--r-- | lib/Math/BigFloat.pm | 127 | ||||
-rw-r--r-- | lib/Math/BigInt.pm | 123 | ||||
-rw-r--r-- | lib/Math/Complex.pm | 65 |
3 files changed, 204 insertions, 111 deletions
diff --git a/lib/Math/BigFloat.pm b/lib/Math/BigFloat.pm index 92e701666f..7551ad01a3 100644 --- a/lib/Math/BigFloat.pm +++ b/lib/Math/BigFloat.pm @@ -5,31 +5,31 @@ use Math::BigInt; use Exporter; # just for use to be happy @ISA = (Exporter); -%OVERLOAD = ( - # Anonymous subroutines: -'+' => sub {new BigFloat &fadd}, -'-' => sub {new BigFloat +use overload +'+' => sub {new Math::BigFloat &fadd}, +'-' => sub {new Math::BigFloat $_[2]? fsub($_[1],${$_[0]}) : fsub(${$_[0]},$_[1])}, -'<=>' => sub {new BigFloat +'<=>' => sub {new Math::BigFloat $_[2]? fcmp($_[1],${$_[0]}) : fcmp(${$_[0]},$_[1])}, -'cmp' => sub {new BigFloat +'cmp' => sub {new Math::BigFloat $_[2]? ($_[1] cmp ${$_[0]}) : (${$_[0]} cmp $_[1])}, -'*' => sub {new BigFloat &fmul}, -'/' => sub {new BigFloat +'*' => sub {new Math::BigFloat &fmul}, +'/' => sub {new Math::BigFloat $_[2]? scalar fdiv($_[1],${$_[0]}) : scalar fdiv(${$_[0]},$_[1])}, -'neg' => sub {new BigFloat &fneg}, -'abs' => sub {new BigFloat &fabs}, +'neg' => sub {new Math::BigFloat &fneg}, +'abs' => sub {new Math::BigFloat &fabs}, qw( "" stringify 0+ numify) # Order of arguments unsignificant -); +; sub new { - my $foo = fnorm($_[1]); - panic("Not a number initialized to BigFloat") if $foo eq "NaN"; - bless \$foo; + 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 @@ -58,21 +58,6 @@ sub stringify { return $n; } -# Arbitrary length float math package -# -# by Mark Biggar -# -# number format -# canonical strings have the form /[+-]\d+E[+-]\d+/ -# Input values can have inbedded whitespace -# Error returns -# 'NaN' An input parameter was "Not a Number" or -# divide by zero or sqrt of negative number -# Division is computed to -# max($div_scale,length(dividend)+length(divisor)) -# digits by default. -# Also used for default sqrt scale - $div_scale = 40; # Rounding modes one of 'even', 'odd', '+inf', '-inf', 'zero' or 'trunc'. @@ -84,21 +69,6 @@ sub fneg; sub fabs; sub fcmp; sub fround; sub ffround; sub fnorm; sub fsqrt; -# bigfloat routines -# -# fadd(NSTR, NSTR) return NSTR addition -# fsub(NSTR, NSTR) return NSTR subtraction -# fmul(NSTR, NSTR) return NSTR multiplication -# fdiv(NSTR, NSTR[,SCALE]) returns NSTR division to SCALE places -# fneg(NSTR) return NSTR negation -# fabs(NSTR) return NSTR absolute value -# fcmp(NSTR,NSTR) return CODE compare undef,<0,=0,>0 -# fround(NSTR, SCALE) return NSTR round to SCALE digits -# ffround(NSTR, SCALE) return NSTR round at SCALEth place -# fnorm(NSTR) return (NSTR) normalize -# fsqrt(NSTR[, SCALE]) return NSTR sqrt to SCALE places - - # Convert a number to canonical string form. # Takes something that looks like a number and converts it to # the form /^[+-]\d+E[+-]\d+$/. @@ -154,7 +124,7 @@ sub fmul { #(fnum_str, fnum_str) return fnum_str &norm(Math::BigInt::bmul($xm,$ym),$xe+$ye); } } - + # addition sub fadd { #(fnum_str, fnum_str) return fnum_str local($x,$y) = (fnorm($_[$[]),fnorm($_[$[+1])); @@ -192,7 +162,7 @@ sub fdiv #(fnum_str, fnum_str[,scale]) return fnum_str $xe-$ye-$scale); } } - + # round int $q based on fraction $r/$base using $rnd_mode sub round { #(int_str, int_str, int_str) return int_str local($q,$r,$base) = @_; @@ -233,7 +203,7 @@ sub fround { #(fnum_str, scale) return fnum_str } } } - + # round $x at the 10 to the $scale digit place sub ffround { #(fnum_str, scale) return fnum_str local($x,$scale) = (fnorm($_[$[]),$_[$[+1]); @@ -273,7 +243,7 @@ sub fcmp #(fnum_str, fnum_str) return cond_code ); } } - + # square root by Newtons method. sub fsqrt { #(fnum_str[, scale]) return fnum_str local($x, $scale) = (fnorm($_[$[]), $_[$[+1]); @@ -290,8 +260,67 @@ sub fsqrt { #(fnum_str[, scale]) return fnum_str $guess = fmul(fadd($guess,fdiv($x,$guess,$gs*2)),".5"); $gs *= 2; } - new BigFloat &fround($guess, $scale); + new Math::BigFloat &fround($guess, $scale); } } 1; +__END__ + +=head1 NAME + +Math::BigFloat - Arbitrary length float math package + +=head1 SYNOPSIS + + use Math::BogFloat; + $f = Math::BigFloat->new($string); + + $f->fadd(NSTR) return NSTR addition + $f->fsub(NSTR) return NSTR subtraction + $f->fmul(NSTR) return NSTR multiplication + $f->fdiv(NSTR[,SCALE]) returns NSTR division to SCALE places + $f->fneg() return NSTR negation + $f->fabs() return NSTR absolute value + $f->fcmp(NSTR) return CODE compare undef,<0,=0,>0 + $f->fround(SCALE) return NSTR round to SCALE digits + $f->ffround(SCALE) return NSTR round at SCALEth place + $f->fnorm() return (NSTR) normalize + $f->fsqrt([SCALE]) return NSTR sqrt to SCALE places + +=head1 DESCRIPTION + +All basic math operations are overloaded if you declare your big +floats as + + $float = new Math::BigFloat "2.123123123123123123123123123123123"; + +=over 2 + +=item number format + +canonical strings have the form /[+-]\d+E[+-]\d+/ . Input values can +have inbedded whitespace. + +=item Error returns 'NaN' + +An input parameter was "Not a Number" or divide by zero or sqrt of +negative number. + +=item Division is computed to + +C<max($div_scale,length(dividend)+length(divisor))> digits by default. +Also used for default sqrt scale. + +=back + +=head1 BUGS + +The current version of this module is a preliminary version of the +real thing that is currently (as of perl5.002) under development. + +=head1 AUTHOR + +Mark Biggar + +=cut diff --git a/lib/Math/BigInt.pm b/lib/Math/BigInt.pm index 8c0ca4e6d4..68856aea6e 100644 --- a/lib/Math/BigInt.pm +++ b/lib/Math/BigInt.pm @@ -1,7 +1,6 @@ package Math::BigInt; -%OVERLOAD = ( - # Anonymous subroutines: +use overload '+' => sub {new Math::BigInt &badd}, '-' => sub {new Math::BigInt $_[2]? bsub($_[1],${$_[0]}) : bsub(${$_[0]},$_[1])}, @@ -23,57 +22,24 @@ package Math::BigInt; qw( "" stringify 0+ numify) # Order of arguments unsignificant -); +; $NaNOK=1; sub new { - my $foo = bnorm($_[1]); + my($class) = shift; + my($foo) = bnorm(shift); die "Not a number initialized to Math::BigInt" if !$NaNOK && $foo eq "NaN"; - bless \$foo; + bless \$foo, $class; } sub stringify { "${$_[0]}" } sub numify { 0 + "${$_[0]}" } # Not needed, additional overhead # comparing to direct compilation based on # stringify -# arbitrary size integer math package -# -# by Mark Biggar -# -# Canonical Big integer value are strings of the form -# /^[+-]\d+$/ with leading zeros suppressed -# Input values to these routines may be strings of the form -# /^\s*[+-]?[\d\s]+$/. -# Examples: -# '+0' canonical zero value -# ' -123 123 123' canonical value '-123123123' -# '1 23 456 7890' canonical value '+1234567890' -# Output values always always in canonical form -# -# Actual math is done in an internal format consisting of an array -# whose first element is the sign (/^[+-]$/) and whose remaining -# elements are base 100000 digits with the least significant digit first. -# The string 'NaN' is used to represent the result when input arguments -# are not numbers, as well as the result of dividing by zero -# -# routines provided are: -# -# bneg(BINT) return BINT negation -# babs(BINT) return BINT absolute value -# bcmp(BINT,BINT) return CODE compare numbers (undef,<0,=0,>0) -# badd(BINT,BINT) return BINT addition -# bsub(BINT,BINT) return BINT subtraction -# bmul(BINT,BINT) return BINT multiplication -# bdiv(BINT,BINT) return (BINT,BINT) division (quo,rem) just quo if scalar -# bmod(BINT,BINT) return BINT modulus -# bgcd(BINT,BINT) return BINT greatest common divisor -# bnorm(BINT) return BINT normalization -# - $zero = 0; - + # normalize string form of number. Strip leading zeros. Strip any # white space and add a sign, if missing. # Strings that are not numbers result the value 'NaN'. @@ -125,7 +91,7 @@ sub abs { # post-normalized abs for internal use s/^-/+/; $_; } - + # Compares 2 values. Returns one of undef, <0, =0, >0. (suitable for sort) sub bcmp { #(num_str, num_str) return cond_code local($x,$y) = (&bnorm($_[$[]),&bnorm($_[$[+1])); @@ -186,7 +152,7 @@ sub bgcd { #(num_str, num_str) return num_str $x; } } - + # routine to add two base 1e5 numbers # stolen from Knuth Vol 2 Algorithm A pg 231 # there are separate routines to add and sub as per Kunth pg 233 @@ -252,7 +218,7 @@ sub mul { #(*int_num_array, *int_num_array) return int_num_array sub bmod { #(num_str, num_str) return num_str (&bdiv(@_))[$[+1]; } - + sub bdiv { #(dividend: num_str, divisor: num_str) return num_str local (*x, *y); ($x, $y) = (&bnorm($_[$[]), &bnorm($_[$[+1])); return wantarray ? ('NaN','NaN') : 'NaN' @@ -347,3 +313,74 @@ sub bpow { #(num_str, num_str) return num_str } 1; +__END__ + +=head1 NAME + +Math::BigInt - Arbitrary size integer math package + +=head1 SYNOPSIS + + use Math::BigInt; + $i = Math::BigInt->new($string); + + $i->bneg return BINT negation + $i->babs return BINT absolute value + $i->bcmp(BINT) return CODE compare numbers (undef,<0,=0,>0) + $i->badd(BINT) return BINT addition + $i->bsub(BINT) return BINT subtraction + $i->bmul(BINT) return BINT multiplication + $i->bdiv(BINT) return (BINT,BINT) division (quo,rem) just quo if scalar + $i->bmod(BINT) return BINT modulus + $i->bgcd(BINT) return BINT greatest common divisor + $i->bnorm return BINT normalization + +=head1 DESCRIPTION + +All basic math operations are overloaded if you declare your big +integers as + + $i = new Math::BigInt '123 456 789 123 456 789'; + + +=over 2 + +=item Canonical notation + +Big integer value are strings of the form C</^[+-]\d+$/> with leading +zeros suppressed. + +=item Input + +Input values to these routines may be strings of the form +C</^\s*[+-]?[\d\s]+$/>. + +=item Output + +Output values always always in canonical form + +=back + +Actual math is done in an internal format consisting of an array +whose first element is the sign (/^[+-]$/) and whose remaining +elements are base 100000 digits with the least significant digit first. +The string 'NaN' is used to represent the result when input arguments +are not numbers, as well as the result of dividing by zero. + +=head1 EXAMPLES + + '+0' canonical zero value + ' -123 123 123' canonical value '-123123123' + '1 23 456 7890' canonical value '+1234567890' + + +=head1 BUGS + +The current version of this module is a preliminary version of the +real thing that is currently (as of perl5.002) under development. + +=head1 AUTHOR + +Mark Biggar, overloaded interface by Ilya Zakharevich. + +=cut diff --git a/lib/Math/Complex.pm b/lib/Math/Complex.pm index a5a40b2486..969f3c2c79 100644 --- a/lib/Math/Complex.pm +++ b/lib/Math/Complex.pm @@ -1,18 +1,3 @@ -# -# Perl5 Package for complex numbers -# -# 1994 by David Nadler -# Coding know-how provided by Tom Christiansen, Tim Bunce, and Larry Wall -# sqrt() added by Tom Christiansen; beware should have two roots, -# but only returns one. (use wantarray?) -# -# -# The functions "Re", "Im", and "arg" are provided. -# "~" is used as the conjugation operator and "abs" is overloaded. -# -# Transcendental functions overloaded: so far only sin, cos, and exp. -# - package Math::Complex; require Exporter; @@ -21,7 +6,7 @@ require Exporter; # just to make use happy -%OVERLOAD= ( +use overload '+' => sub { my($x1,$y1,$x2,$y2) = (@{$_[0]},@{$_[1]}); bless [ $x1+$x2, $y1+$y2]; }, @@ -95,12 +80,12 @@ require Exporter; }, qw("" stringify) -); +; sub new { - shift; + my $class = shift; my @C = @_; - bless \@C; + bless \@C, $class; } sub Re { @@ -134,3 +119,45 @@ sub stringify { $_ = 0 if ($_ eq ''); return $_; } + +1; +__END__ + +=head1 NAME + +Math::Complex - complex numbers package + +=head1 SYNOPSIS + + use Math::Complex; + $i = new Math::Complex; + +=head1 DESCRIPTION + +Complex numbers declared as + + $i = Math::Complex->new(1,1); + +can be manipulated with overloaded math operators. The operators + + + - * / neg ~ abs cos sin exp sqrt + +are supported as well as + + "" (stringify) + +The methods + + Re Im arg + +are also provided. + +=head1 BUGS + +sqrt() should return two roots, but only returns one. + +=head1 AUTHORS + +Dave Nadler, Tom Christiansen, Tim Bunce, Larry Wall. + +=cut |