1#!/usr/bin/perl -w 2 3use strict; 4use Test; 5 6BEGIN 7 { 8 $| = 1; 9 chdir 't' if -d 't'; 10 unshift @INC, '../lib'; # for running manually 11 plan tests => 174; 12 } 13 14# testing of Math::BigRat 15 16use Math::BigRat; 17use Math::BigInt; 18use Math::BigFloat; 19 20# shortcuts 21my $cr = 'Math::BigRat'; 22my $mbi = 'Math::BigInt'; 23my $mbf = 'Math::BigFloat'; 24 25my ($x,$y,$z); 26 27$x = Math::BigRat->new(1234); ok ($x,1234); 28ok ($x->isa('Math::BigRat')); 29ok (!$x->isa('Math::BigFloat')); 30ok (!$x->isa('Math::BigInt')); 31 32############################################################################## 33# new and bnorm() 34 35foreach my $func (qw/new bnorm/) 36 { 37 $x = $cr->$func(1234); ok ($x,1234); 38 39 $x = $cr->$func('1234/1'); ok ($x,1234); 40 $x = $cr->$func('1234/2'); ok ($x,617); 41 42 $x = $cr->$func('100/1.0'); ok ($x,100); 43 $x = $cr->$func('10.0/1.0'); ok ($x,10); 44 $x = $cr->$func('0.1/10'); ok ($x,'1/100'); 45 $x = $cr->$func('0.1/0.1'); ok ($x,'1'); 46 $x = $cr->$func('1e2/10'); ok ($x,10); 47 $x = $cr->$func('5/1e2'); ok ($x,'1/20'); 48 $x = $cr->$func('1e2/1e1'); ok ($x,10); 49 $x = $cr->$func('1 / 3'); ok ($x,'1/3'); 50 $x = $cr->$func('-1 / 3'); ok ($x,'-1/3'); 51 $x = $cr->$func('NaN'); ok ($x,'NaN'); 52 $x = $cr->$func('inf'); ok ($x,'inf'); 53 $x = $cr->$func('-inf'); ok ($x,'-inf'); 54 $x = $cr->$func('1/'); ok ($x,'NaN'); 55 56 # input ala '1+1/3' isn't parsed ok yet 57 $x = $cr->$func('1+1/3'); ok ($x,'NaN'); 58 59 $x = $cr->$func('1/1.2'); ok ($x,'5/6'); 60 $x = $cr->$func('1.3/1.2'); ok ($x,'13/12'); 61 $x = $cr->$func('1.2/1'); ok ($x,'6/5'); 62 63 ############################################################################ 64 # other classes as input 65 66 $x = $cr->$func($mbi->new(1231)); ok ($x,'1231'); 67 $x = $cr->$func($mbf->new(1232)); ok ($x,'1232'); 68 $x = $cr->$func($mbf->new(1232.3)); ok ($x,'12323/10'); 69 } 70 71$x = $cr->new('-0'); ok ($x,'0'); ok ($x->{_n}, '0'); ok ($x->{_d},'1'); 72$x = $cr->new('NaN'); ok ($x,'NaN'); ok ($x->{_n}, '0'); ok ($x->{_d},'0'); 73$x = $cr->new('-NaN'); ok ($x,'NaN'); ok ($x->{_n}, '0'); ok ($x->{_d},'0'); 74$x = $cr->new('-1r4'); ok ($x,'NaN'); ok ($x->{_n}, '0'); ok ($x->{_d},'0'); 75 76$x = $cr->new('+inf'); ok ($x,'inf'); ok ($x->{_n}, '0'); ok ($x->{_d},'0'); 77$x = $cr->new('-inf'); ok ($x,'-inf'); ok ($x->{_n}, '0'); ok ($x->{_d},'0'); 78$x = $cr->new('123a4'); ok ($x,'NaN'); ok ($x->{_n}, '0'); ok ($x->{_d},'0'); 79 80# wrong inputs 81$x = $cr->new('1e2e2'); ok ($x,'NaN'); ok ($x->{_n}, '0'); ok ($x->{_d},'0'); 82$x = $cr->new('1+2+2'); ok ($x,'NaN'); ok ($x->{_n}, '0'); ok ($x->{_d},'0'); 83# failed due to BigFlaot bug 84$x = $cr->new('1.2.2'); ok ($x,'NaN'); ok ($x->{_n}, '0'); ok ($x->{_d},'0'); 85 86ok ($cr->new('123a4'),'NaN'); 87ok ($cr->new('123e4'),'1230000'); 88ok ($cr->new('-NaN'),'NaN'); 89ok ($cr->new('NaN'),'NaN'); 90ok ($cr->new('+inf'),'inf'); 91ok ($cr->new('-inf'),'-inf'); 92 93############################################################################## 94# mixed arguments 95 96ok ($cr->new('3/7')->badd(1),'10/7'); 97ok ($cr->new('3/10')->badd(1.1),'7/5'); 98ok ($cr->new('3/7')->badd($mbi->new(1)),'10/7'); 99ok ($cr->new('3/10')->badd($mbf->new('1.1')),'7/5'); 100 101ok ($cr->new('3/7')->bsub(1),'-4/7'); 102ok ($cr->new('3/10')->bsub(1.1),'-4/5'); 103ok ($cr->new('3/7')->bsub($mbi->new(1)),'-4/7'); 104ok ($cr->new('3/10')->bsub($mbf->new('1.1')),'-4/5'); 105 106ok ($cr->new('3/7')->bmul(1),'3/7'); 107ok ($cr->new('3/10')->bmul(1.1),'33/100'); 108ok ($cr->new('3/7')->bmul($mbi->new(1)),'3/7'); 109ok ($cr->new('3/10')->bmul($mbf->new('1.1')),'33/100'); 110 111ok ($cr->new('3/7')->bdiv(1),'3/7'); 112ok ($cr->new('3/10')->bdiv(1.1),'3/11'); 113ok ($cr->new('3/7')->bdiv($mbi->new(1)),'3/7'); 114ok ($cr->new('3/10')->bdiv($mbf->new('1.1')),'3/11'); 115 116############################################################################## 117$x = $cr->new('1/4'); $y = $cr->new('1/3'); 118 119ok ($x + $y, '7/12'); 120ok ($x * $y, '1/12'); 121ok ($x / $y, '3/4'); 122 123$x = $cr->new('7/5'); $x *= '3/2'; 124ok ($x,'21/10'); 125$x -= '0.1'; 126ok ($x,'2'); # not 21/10 127 128$x = $cr->new('2/3'); $y = $cr->new('3/2'); 129ok ($x > $y,''); 130ok ($x < $y,1); 131ok ($x == $y,''); 132 133$x = $cr->new('-2/3'); $y = $cr->new('3/2'); 134ok ($x > $y,''); 135ok ($x < $y,'1'); 136ok ($x == $y,''); 137 138$x = $cr->new('-2/3'); $y = $cr->new('-2/3'); 139ok ($x > $y,''); 140ok ($x < $y,''); 141ok ($x == $y,'1'); 142 143$x = $cr->new('-2/3'); $y = $cr->new('-1/3'); 144ok ($x > $y,''); 145ok ($x < $y,'1'); 146ok ($x == $y,''); 147 148$x = $cr->new('-124'); $y = $cr->new('-122'); 149ok ($x->bacmp($y),1); 150 151$x = $cr->new('-124'); $y = $cr->new('-122'); 152ok ($x->bcmp($y),-1); 153 154$x = $cr->new('3/7'); $y = $cr->new('5/7'); 155ok ($x+$y,'8/7'); 156 157$x = $cr->new('3/7'); $y = $cr->new('5/7'); 158ok ($x*$y,'15/49'); 159 160$x = $cr->new('3/5'); $y = $cr->new('5/7'); 161ok ($x*$y,'3/7'); 162 163$x = $cr->new('3/5'); $y = $cr->new('5/7'); 164ok ($x/$y,'21/25'); 165 166$x = $cr->new('7/4'); $y = $cr->new('1'); 167ok ($x % $y,'3/4'); 168 169$x = $cr->new('7/4'); $y = $cr->new('5/13'); 170ok ($x % $y,'11/52'); 171 172$x = $cr->new('7/4'); $y = $cr->new('5/9'); 173ok ($x % $y,'1/12'); 174 175$x = $cr->new('-144/9')->bsqrt(); ok ($x,'NaN'); 176$x = $cr->new('144/9')->bsqrt(); ok ($x,'4'); 177$x = $cr->new('3/4')->bsqrt(); ok ($x, 178 '1732050807568877293527446341505872366943/' 179 .'2000000000000000000000000000000000000000'); 180 181############################################################################## 182# bpow 183 184$x = $cr->new('2/1'); $z = $x->bpow('3/1'); ok ($x,'8'); 185$x = $cr->new('1/2'); $z = $x->bpow('3/1'); ok ($x,'1/8'); 186$x = $cr->new('1/3'); $z = $x->bpow('4/1'); ok ($x,'1/81'); 187$x = $cr->new('2/3'); $z = $x->bpow('4/1'); ok ($x,'16/81'); 188 189# XXX todo: 190#$x = $cr->new('2/3'); $z = $x->bpow('5/3'); ok ($x,'32/81 ???'); 191 192############################################################################## 193# bfac 194 195$x = $cr->new('1'); $x->bfac(); ok ($x,'1'); 196for (my $i = 0; $i < 8; $i++) 197 { 198 $x = $cr->new("$i/1")->bfac(); ok ($x,$mbi->new($i)->bfac()); 199 } 200 201# test for $self->bnan() vs. $x->bnan(); 202$x = $cr->new('-1'); $x->bfac(); ok ($x,'NaN'); 203 204############################################################################## 205# binc/bdec 206 207$x = $cr->new('3/2'); ok ($x->binc(),'5/2'); 208$x = $cr->new('15/6'); ok ($x->bdec(),'3/2'); 209 210############################################################################## 211# bfloor/bceil 212 213$x = $cr->new('-7/7'); ok ($x->{_n}, '1'); ok ($x->{_d}, '1'); 214$x = $cr->new('-7/7')->bfloor(); ok ($x->{_n}, '1'); ok ($x->{_d}, '1'); 215 216############################################################################## 217# bsstr 218 219$x = $cr->new('7/5')->bsstr(); ok ($x,'7/5'); 220$x = $cr->new('-7/5')->bsstr(); ok ($x,'-7/5'); 221 222############################################################################## 223# numify() 224 225my @array = qw/1 2 3 4 5 6 7 8 9/; 226$x = $cr->new('8/8'); ok ($array[$x],2); 227$x = $cr->new('16/8'); ok ($array[$x],3); 228$x = $cr->new('17/8'); ok ($array[$x],3); 229$x = $cr->new('33/8'); ok ($array[$x],5); 230$x = $cr->new('-33/8'); ok ($array[$x],6); 231 232$x = $cr->new('33/8'); ok ($x->numify() * 1000, 4125); 233$x = $cr->new('-33/8'); ok ($x->numify() * 1000, -4125); 234$x = $cr->new('inf'); ok ($x->numify(), 'inf'); 235$x = $cr->new('-inf'); ok ($x->numify(), '-inf'); 236$x = $cr->new('NaN'); ok ($x->numify(), 'NaN'); 237 238$x = $cr->new('4/3'); ok ($x->numify(), 4/3); 239 240############################################################################## 241# broot(), bmodpow() and bmodinv() 242 243$x = $cr->new(2) ** 32; 244$y = $cr->new(4); 245$z = $cr->new(3); 246 247ok ($x->copy()->broot($y), 2 ** 8); 248ok (ref($x->copy()->broot($y)), $cr); 249 250 251ok ($x->copy()->bmodpow($y,$z), 1); 252ok (ref($x->copy()->bmodpow($y,$z)), $cr); 253 254$x = $cr->new(8); 255$y = $cr->new(5033); 256$z = $cr->new(4404); 257 258ok ($x->copy()->bmodinv($y), $z); 259ok (ref($x->copy()->bmodinv($y)), $cr); 260 261# square root with exact result 262$x = $cr->new('1.44'); 263ok ($x->copy()->broot(2), '12/10'); 264ok (ref($x->copy()->broot(2)), $cr); 265 266# log with exact result 267$x = $cr->new('256.1'); 268ok ($x->copy()->blog(2), '8000563442710106079310294693803606983661/1000000000000000000000000000000000000000'); 269ok (ref($x->copy()->blog(2)), $cr); 270 271 272############################################################################## 273# done 274 2751; 276 277