40 lines
1.3 KiB
Raku
40 lines
1.3 KiB
Raku
use Math::BigRat try=>"GMP";
|
|
|
|
sub taneval {
|
|
my($coef,$f) = @_;
|
|
$f = Math::BigRat->new($f) unless ref($f);
|
|
return 0 if $coef == 0;
|
|
return $f if $coef == 1;
|
|
return -taneval(-$coef, $f) if $coef < 0;
|
|
my($a,$b) = ( taneval($coef>>1, $f), taneval($coef-($coef>>1),$f) );
|
|
($a+$b)/(1-$a*$b);
|
|
}
|
|
|
|
sub tans {
|
|
my @xs=@_;
|
|
return taneval(@{$xs[0]}) if scalar(@xs)==1;
|
|
my($a,$b) = ( tans(@xs[0..($#xs>>1)]), tans(@xs[($#xs>>1)+1..$#xs]) );
|
|
($a+$b)/(1-$a*$b);
|
|
}
|
|
|
|
sub test {
|
|
printf "%5s (%s)\n", (tans(@_)==1)?"OK":"Error", join(" ",map{"[@$_]"} @_);
|
|
}
|
|
|
|
test([1,'1/2'], [1,'1/3']);
|
|
test([2,'1/3'], [1,'1/7']);
|
|
test([4,'1/5'], [-1,'1/239']);
|
|
test([5,'1/7'],[2,'3/79']);
|
|
test([5,'29/278'],[7,'3/79']);
|
|
test([1,'1/2'],[1,'1/5'],[1,'1/8']);
|
|
test([4,'1/5'],[-1,'1/70'],[1,'1/99']);
|
|
test([5,'1/7'],[4,'1/53'],[2,'1/4443']);
|
|
test([6,'1/8'],[2,'1/57'],[1,'1/239']);
|
|
test([8,'1/10'],[-1,'1/239'],[-4,'1/515']);
|
|
test([12,'1/18'],[8,'1/57'],[-5,'1/239']);
|
|
test([16,'1/21'],[3,'1/239'],[4,'3/1042']);
|
|
test([22,'1/28'],[2,'1/443'],[-5,'1/1393'],[-10,'1/11018']);
|
|
test([22,'1/38'],[17,'7/601'],[10,'7/8149']);
|
|
test([44,'1/57'],[7,'1/239'],[-12,'1/682'],[24,'1/12943']);
|
|
test([88,'1/172'],[51,'1/239'],[32,'1/682'],[44,'1/5357'],[68,'1/12943']);
|
|
test([88,'1/172'],[51,'1/239'],[32,'1/682'],[44,'1/5357'],[68,'1/12944']);
|