This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Upgrade to Math::BigRat 0.11
[perl5.git] / lib / Math / BigRat / t / bigrat.t
1 #!/usr/bin/perl -w
2
3 use strict;
4 use Test;
5
6 BEGIN 
7   {
8   $| = 1;
9   chdir 't' if -d 't';
10   unshift @INC, '../lib'; # for running manually
11   plan tests => 170;
12   }
13
14 # testing of Math::BigRat
15
16 use Math::BigRat;
17 use Math::BigInt;
18 use Math::BigFloat;
19
20 # shortcuts
21 my $cr = 'Math::BigRat';                
22 my $mbi = 'Math::BigInt';
23 my $mbf = 'Math::BigFloat';
24
25 my ($x,$y,$z);
26
27 $x = Math::BigRat->new(1234);           ok ($x,1234);
28 ok ($x->isa('Math::BigRat'));
29 ok (!$x->isa('Math::BigFloat'));
30 ok (!$x->isa('Math::BigInt'));
31
32 ##############################################################################
33 # new and bnorm()
34
35 foreach 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
86 ok ($cr->new('123a4'),'NaN');
87 ok ($cr->new('123e4'),'1230000');
88 ok ($cr->new('-NaN'),'NaN');
89 ok ($cr->new('NaN'),'NaN');
90 ok ($cr->new('+inf'),'inf');
91 ok ($cr->new('-inf'),'-inf');
92
93 ##############################################################################
94 # mixed arguments
95
96 ok ($cr->new('3/7')->badd(1),'10/7');
97 ok ($cr->new('3/10')->badd(1.1),'7/5');
98 ok ($cr->new('3/7')->badd($mbi->new(1)),'10/7');
99 ok ($cr->new('3/10')->badd($mbf->new('1.1')),'7/5');
100
101 ok ($cr->new('3/7')->bsub(1),'-4/7');
102 ok ($cr->new('3/10')->bsub(1.1),'-4/5');
103 ok ($cr->new('3/7')->bsub($mbi->new(1)),'-4/7');
104 ok ($cr->new('3/10')->bsub($mbf->new('1.1')),'-4/5');
105
106 ok ($cr->new('3/7')->bmul(1),'3/7');
107 ok ($cr->new('3/10')->bmul(1.1),'33/100');
108 ok ($cr->new('3/7')->bmul($mbi->new(1)),'3/7');
109 ok ($cr->new('3/10')->bmul($mbf->new('1.1')),'33/100');
110
111 ok ($cr->new('3/7')->bdiv(1),'3/7');
112 ok ($cr->new('3/10')->bdiv(1.1),'3/11');
113 ok ($cr->new('3/7')->bdiv($mbi->new(1)),'3/7');
114 ok ($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 ok ($x + $y, '7/12');
119 ok ($x * $y, '1/12');
120 ok ($x / $y, '3/4');
121
122 $x = $cr->new('7/5'); $x *= '3/2'; 
123 ok ($x,'21/10');
124 $x -= '0.1';
125 ok ($x,'2');    # not 21/10
126
127 $x = $cr->new('2/3');           $y = $cr->new('3/2');
128 ok ($x > $y,'');                
129 ok ($x < $y,1);
130 ok ($x == $y,'');
131
132 $x = $cr->new('-2/3');          $y = $cr->new('3/2');
133 ok ($x > $y,'');                
134 ok ($x < $y,'1');
135 ok ($x == $y,'');
136
137 $x = $cr->new('-2/3');          $y = $cr->new('-2/3');
138 ok ($x > $y,'');                
139 ok ($x < $y,'');
140 ok ($x == $y,'1');
141
142 $x = $cr->new('-2/3');          $y = $cr->new('-1/3');
143 ok ($x > $y,'');                
144 ok ($x < $y,'1');
145 ok ($x == $y,'');
146
147 $x = $cr->new('-124');          $y = $cr->new('-122');
148 ok ($x->bacmp($y),1);
149
150 $x = $cr->new('-124');          $y = $cr->new('-122');
151 ok ($x->bcmp($y),-1);
152
153 $x = $cr->new('3/7');           $y = $cr->new('5/7');
154 ok ($x+$y,'8/7');
155
156 $x = $cr->new('3/7');           $y = $cr->new('5/7');
157 ok ($x*$y,'15/49');
158
159 $x = $cr->new('3/5');           $y = $cr->new('5/7');
160 ok ($x*$y,'3/7');
161
162 $x = $cr->new('3/5');           $y = $cr->new('5/7');
163 ok ($x/$y,'21/25');
164
165 $x = $cr->new('7/4');           $y = $cr->new('1');
166 ok ($x % $y,'3/4');
167
168 $x = $cr->new('7/4');           $y = $cr->new('5/13');
169 ok ($x % $y,'11/52');
170
171 $x = $cr->new('7/4');           $y = $cr->new('5/9');
172 ok ($x % $y,'1/12');
173
174 $x = $cr->new('-144/9')->bsqrt();       ok ($x,'NaN');
175 $x = $cr->new('144/9')->bsqrt();        ok ($x,'4');
176 $x = $cr->new('3/4')->bsqrt();          ok ($x,
177   '1732050807568877293527446341505872366943/'
178  .'2000000000000000000000000000000000000000');
179
180 ##############################################################################
181 # bpow
182
183 $x = $cr->new('2/1');  $z = $x->bpow('3/1'); ok ($x,'8');
184 $x = $cr->new('1/2');  $z = $x->bpow('3/1'); ok ($x,'1/8');
185 $x = $cr->new('1/3');  $z = $x->bpow('4/1'); ok ($x,'1/81');
186 $x = $cr->new('2/3');  $z = $x->bpow('4/1'); ok ($x,'16/81');
187
188 # XXX todo:
189 #$x = $cr->new('2/3');  $z = $x->bpow('5/3'); ok ($x,'32/81 ???');
190
191 ##############################################################################
192 # bfac
193
194 $x = $cr->new('1');  $x->bfac(); ok ($x,'1');
195 for (my $i = 0; $i < 8; $i++)
196   {
197   $x = $cr->new("$i/1")->bfac(); ok ($x,$mbi->new($i)->bfac());
198   }
199
200 # test for $self->bnan() vs. $x->bnan();
201 $x = $cr->new('-1'); $x->bfac(); ok ($x,'NaN'); 
202
203 ##############################################################################
204 # binc/bdec
205
206 $x =  $cr->new('3/2'); ok ($x->binc(),'5/2');
207 $x =  $cr->new('15/6'); ok ($x->bdec(),'3/2');
208
209 ##############################################################################
210 # bfloor/bceil
211
212 $x = $cr->new('-7/7'); ok ($x->{_n}, '1'); ok ($x->{_d}, '1');
213 $x = $cr->new('-7/7')->bfloor(); ok ($x->{_n}, '1'); ok ($x->{_d}, '1');
214
215 ##############################################################################
216 # bsstr
217
218 $x = $cr->new('7/5')->bsstr(); ok ($x,'7/5');
219 $x = $cr->new('-7/5')->bsstr(); ok ($x,'-7/5');
220
221 ##############################################################################
222 # numify()
223
224 my @array = qw/1 2 3 4 5 6 7 8 9/;
225 $x = $cr->new('8/8'); ok ($array[$x],2);
226 $x = $cr->new('16/8'); ok ($array[$x],3);
227 $x = $cr->new('17/8'); ok ($array[$x],3);
228 $x = $cr->new('33/8'); ok ($array[$x],5);
229 $x = $cr->new('-33/8'); ok ($array[$x],6);
230
231 $x = $cr->new('33/8'); ok ($x->numify() * 1000, 4125);
232 $x = $cr->new('-33/8'); ok ($x->numify() * 1000, -4125);
233 $x = $cr->new('inf'); ok ($x->numify(), 'inf');
234 $x = $cr->new('-inf'); ok ($x->numify(), '-inf');
235 $x = $cr->new('NaN'); ok ($x->numify(), 'NaN');
236
237 $x = $cr->new('4/3'); ok ($x->numify(), 4/3);
238
239 ##############################################################################
240 # broot(), bmodpow() and bmodinv()
241
242 $x = $cr->new(2) ** 32;
243 $y = $cr->new(4);
244 $z = $cr->new(3);
245
246 ok ($x->copy()->broot($y), 2 ** 8);
247 ok (ref($x->copy()->broot($y)), $cr);
248
249 ok ($x->copy()->bmodpow($y,$z), 1);
250 ok (ref($x->copy()->bmodpow($y,$z)), $cr);
251
252 $x = $cr->new(8);
253 $y = $cr->new(5033);
254 $z = $cr->new(4404);
255
256 ok ($x->copy()->bmodinv($y), $z);
257 ok (ref($x->copy()->bmodinv($y)), $cr);
258
259 ##############################################################################
260 # done
261
262 1;
263