1package Math::BigRat::Test; 2 3require 5.006; 4use strict; 5use warnings; 6 7use Exporter; 8use Math::BigRat; 9use Math::BigFloat; 10 11our @ISA = qw(Math::BigRat Exporter); 12our $VERSION = '0.04'; 13 14use overload; # inherit overload from BigRat 15 16# Globals 17our $accuracy = undef; 18our $precision = undef; 19our $round_mode = 'even'; 20our $div_scale = 40; 21 22my $class = 'Math::BigRat::Test'; 23 24#sub new { 25# my $proto = shift; 26# my $class = ref($proto) || $proto; 27# 28# my $value = shift; 29# my $a = $accuracy; $a = $_[0] if defined $_[0]; 30# my $p = $precision; $p = $_[1] if defined $_[1]; 31# # Store the floating point value 32# my $self = Math::BigFloat->new($value, $a, $p, $round_mode); 33# bless $self, $class; 34# $self->{'_custom'} = 1; # make sure this never goes away 35# return $self; 36#} 37 38BEGIN { 39 *fstr = \&bstr; 40 *fsstr = \&bsstr; 41 *objectify = \&Math::BigInt::objectify; 42 *AUTOLOAD = \&Math::BigRat::AUTOLOAD; 43 no strict 'refs'; 44 foreach my $method (qw/div acmp floor ceil root sqrt log fac modpow modinv/) { 45 *{'b' . $method} = \&{'Math::BigRat::b' . $method}; 46 } 47} 48 49sub fround { 50 my ($x, $a) = @_; 51 52 #print "$a $accuracy $precision $round_mode\n"; 53 Math::BigFloat->round_mode($round_mode); 54 Math::BigFloat->accuracy($a || $accuracy); 55 Math::BigFloat->precision(undef); 56 my $y = Math::BigFloat->new($x->bsstr(), undef, undef); 57 $class->new($y->fround($a)); 58} 59 60sub ffround { 61 my ($x, $p) = @_; 62 63 Math::BigFloat->round_mode($round_mode); 64 Math::BigFloat->accuracy(undef); 65 Math::BigFloat->precision($p || $precision); 66 my $y = Math::BigFloat->new($x->bsstr(), undef, undef); 67 $class->new($y->ffround($p)); 68} 69 70sub bstr { 71 # calculate a BigFloat compatible string output 72 my ($x) = @_; 73 74 $x = $class->new($x) unless ref $x; 75 76 if ($x->{sign} !~ /^[+-]$/) { # inf, NaN etc 77 my $s = $x->{sign}; 78 $s =~ s/^\+//; # +inf => inf 79 return $s; 80 } 81 82 my $s = ''; 83 $s = $x->{sign} if $x->{sign} ne '+'; # +3 vs 3 84 85 # print " bstr \$x ", $accuracy || $x->{_a} || 'notset', " ", $precision || $x->{_p} || 'notset', "\n"; 86 return $s.$x->{_n} if $x->{_d}->is_one(); 87 my $output = Math::BigFloat->new($x->{_n})->bdiv($x->{_d}); 88 local $Math::BigFloat::accuracy = $accuracy || $x->{_a}; 89 local $Math::BigFloat::precision = $precision || $x->{_p}; 90 $s.$output->bstr(); 91} 92 93sub numify { 94 $_[0]->bsstr(); 95} 96 97sub bsstr { 98 # calculate a BigFloat compatible string output 99 my ($x) = @_; 100 101 $x = $class->new($x) unless ref $x; 102 103 if ($x->{sign} !~ /^[+-]$/) { # inf, NaN etc 104 my $s = $x->{sign}; 105 $s =~ s/^\+//; # +inf => inf 106 return $s; 107 } 108 109 my $s = ''; 110 $s = $x->{sign} if $x->{sign} ne '+'; # +3 vs 3 111 112 my $output = Math::BigFloat->new($x->{_n})->bdiv($x->{_d}); 113 return $s.$output->bsstr(); 114} 115 1161; 117