I have this calculator code I found very useful. Some of it I have taken from somewhere else. I added some documentation and the $ans variable.
Regards. Mario
#!/usr/bin/perl
#$Id: calcme,v 1.4 2001/10/04 18:00:57 mstorti Exp $
$input=shift;
# require "$ENV{'HOME'}/perl/math.pl";
if ($input eq "-h") {
print <<'EOM';
CALCME: a simple (Perl based) line calculator
usage :
* Compute an expression (remember to enclose <expression> in quotes or
+ double quotes
in order to avoid shell expansion )
$ calc <expression>
<result>
* Interactive use:
$ calc
> <expression>
<result>
> <expression>
<result>
...
Can define variables as in;
> $pi=atan(1,0)*2
> $pi=atan2(1,0)*2
3.14159265358979
> $e=exp(1)
2.71828182845905
> $a=$pi*$e**2
23.2134043573634
>
* Get help (prints this message):
$ calc -u
EOM
goto EXIT;
}
@ans=();
do {print "> ",eval $input,"\n"; goto EXIT;
} if $input;
print "> ";
while (<STDIN>) {
print $ans=eval(),"\n> ";
unshift @ans,$ans;
}
EXIT: ;
Some useful mathematical routines are in "math.pl". If you want to use it uncomment the line and put it somewhere.
#
# Some useful definitions for use with ePerl
#
$PI=2*atan2(1.,0.);
$E=exp(1.);
sub round {
my $x = shift();
my $y = shift();
$y = 1 unless $y;
return floor($x/$y + 0.5);
}
sub floor {
my $x = shift();
my $y = shift();
$y = 1 unless $y;
my $rr = $x/$y;
my $r = int($rr);
$r-- if $rr<0;
return $r;
}
sub ceil {
return floor(@_)+1;
}
sub asin {
my $x=shift();
return atan2($x,sqrt(1-$x*$x));
}
sub acos {
my $x=shift();
return atan2(sqrt(1-$x*$x),$x);
}
sub sinh {
my $x=shift();
return (exp($x)-exp(-$x))/2.;
}
sub cosh {
my $x=shift();
return (exp($x)+exp(-$x))/2.;
}
sub tanh {
my $x=shift();
return sinh($x)/cosh($x);
}
sub acosh {
my $y=shift();
die "acosh: argument must be >1!\n" if $y<1;
return log($y+sqrt($y*$y-1));
}
sub asinh {
my $y=shift();
return log($y+sqrt($y*$y+1.));
}
sub atanh {
my $y=shift();
die "atanh: argument x must be |x| < 1.\n" if abs($y)>=1;
return log((1+$y)/(1-$y))/2.;
}
sub asin {
my $y=shift();
return atan2($y,sqrt(1-$y**2));
}
sub log10 {
my $y=shift();
return log($y)/log(10.);
}
# Returns a number floored to a grid of the form 1,2,5,10,20,50, etc..
+.
# The grid may be changed.
#
# Usage: log_floor($x) - floors to the standard grid 1,2,5
+,10,...
# log_floor($x,'fine') - floors to a fine grid 1,1.5,2,3,4
+,5,7,10,...
# log_floor($x,[1,1.5,2,3,4,5,6,7,8,9,10]) - floors to a use
+r defined grid
# the grid starts
+ in 1 and ends in 10.
sub log_floor {
my $x = shift();
return $x if $x==0;
my $sign=1;
if ($x<0) {
$sign=-1;
$x = -$x;
}
$log10 = log($x)/log(10.);
$expo = floor($log10);
$man = 10**($log10-$expo);
my $grid = shift();
$grid = [1,1.5,2,3,4,5,7,10] if $grid eq 'fine';
$grid = [1,2,4,8,10] if $grid eq 'binary';
$grid = [1,2,5,10] unless $grid; # default grid
for($j=1; $j<=$#{$grid}; $j++) {
$r = $grid->[$j];
return $sign*$grid->[$j-1]*(10**$expo) if $man<$r;
}
}
# Returns a number ceiled to a grid of the form 1,2,5,10,20,50, etc...
# The grid may be changed.
#
# Usage: see log_floor
#
sub log_ceil {
my $x = shift();
return $x if $x==0;
my $sign=1;
if ($x<0) {
$sign=-1;
$x = -$x;
}
$log10 = log($x)/log(10.);
$expo = floor($log10);
$man = 10**($log10-$expo);
my $grid = shift();
$grid = [1,1.5,2,3,4,5,7,10] if $grid eq 'fine';
$grid = [1,2,4,8,10] if $grid eq 'binary';
$grid = [1,2,5,10] unless $grid; # default grid
foreach $r (@{$grid}) {
return $sign*$r*(10**$expo) if $man<$r;
}
}
sub refine {
$nup=shift();
my @nu=@{$nup};
my $nu1=shift();
my $nu2=shift();
if ($#nu==-1) {
$nu=$nu1;
# print "paso por 1\n";
} elsif ($#nu==0) {
$nu=$nu2;
# print "paso por 2\n";
} else {
for ($k=0;$k<$#nu;$k++) {
# print "k: $k\n";
$dif=$nu[$k+1]-$nu[$k];
# print "dif: $dif\n";
if ($k==0 || $dif>$difmax) {
$difmax=$dif;
$kmin=$k;
}
}
# print "intervalo minimo entre ",$nu[$kmin]," y ",$nu[$kmin+1],"\n
+";
$nu=($nu[$kmin]+$nu[$kmin+1])/2;
}
push @nu,$nu;
@nu = sort @nu;
@{$nup}=@nu;
return $nu;
}
sub max {
my $maxx = $_[0];
for (my $j=1; $j<$#_; $j++ ) {
$maxx = $_[$j] if $_[$j]>$maxx;
}
return $maxx;
}
sub min {
my $minn = $_[0];
for (my $j=1; $j<$#_; $j++ ) {
print "minn: cur val: $_[$j]\n";
$minn = $_[$j] if $_[$j]<$minn;
}
return $minn;
}
1;
|