Commit | Line | Data |
---|---|---|
184f15d5 JH |
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 | |
c6c613ed | 11 | plan tests => 200; |
184f15d5 JH |
12 | } |
13 | ||
12fc2493 | 14 | # basic testing of Math::BigRat |
184f15d5 JH |
15 | |
16 | use Math::BigRat; | |
6de7f0cc JH |
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'; | |
184f15d5 JH |
24 | |
25 | my ($x,$y,$z); | |
26 | ||
27 | $x = Math::BigRat->new(1234); ok ($x,1234); | |
8f675a64 JH |
28 | ok ($x->isa('Math::BigRat')); |
29 | ok (!$x->isa('Math::BigFloat')); | |
30 | ok (!$x->isa('Math::BigInt')); | |
31 | ||
32 | ############################################################################## | |
6de7f0cc | 33 | # new and bnorm() |
8f675a64 | 34 | |
6de7f0cc JH |
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); | |
990fb837 | 47 | $x = $cr->$func('5/1e2'); ok ($x,'1/20'); |
6de7f0cc | 48 | $x = $cr->$func('1e2/1e1'); ok ($x,10); |
a4e2b1c6 | 49 | $x = $cr->$func('1 / 3'); ok ($x,'1/3'); |
6de7f0cc | 50 | $x = $cr->$func('-1 / 3'); ok ($x,'-1/3'); |
a4e2b1c6 JH |
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'); | |
6de7f0cc | 55 | |
c6c613ed CBW |
56 | $x = $cr->$func("0x7e"); ok($x, 126); |
57 | ||
6de7f0cc | 58 | # input ala '1+1/3' isn't parsed ok yet |
a4e2b1c6 | 59 | $x = $cr->$func('1+1/3'); ok ($x,'NaN'); |
990fb837 RGS |
60 | |
61 | $x = $cr->$func('1/1.2'); ok ($x,'5/6'); | |
62 | $x = $cr->$func('1.3/1.2'); ok ($x,'13/12'); | |
63 | $x = $cr->$func('1.2/1'); ok ($x,'6/5'); | |
6de7f0cc JH |
64 | |
65 | ############################################################################ | |
66 | # other classes as input | |
67 | ||
a4e2b1c6 JH |
68 | $x = $cr->$func($mbi->new(1231)); ok ($x,'1231'); |
69 | $x = $cr->$func($mbf->new(1232)); ok ($x,'1232'); | |
6de7f0cc JH |
70 | $x = $cr->$func($mbf->new(1232.3)); ok ($x,'12323/10'); |
71 | } | |
9b924220 | 72 | |
12fc2493 AMS |
73 | my $n = 'numerator'; |
74 | my $d = 'denominator'; | |
a4e2b1c6 | 75 | |
12fc2493 AMS |
76 | $x = $cr->new('-0'); ok ($x,'0'); ok ($x->$n(), '0'); ok ($x->$d(),'1'); |
77 | $x = $cr->new('NaN'); ok ($x,'NaN'); ok ($x->$n(), 'NaN'); ok ($x->$d(),'NaN'); | |
78 | $x = $cr->new('-NaN'); ok ($x,'NaN'); ok ($x->$n(), 'NaN'); ok ($x->$d(),'NaN'); | |
79 | $x = $cr->new('-1r4'); ok ($x,'NaN'); ok ($x->$n(), 'NaN'); ok ($x->$d(),'NaN'); | |
80 | ||
81 | $x = $cr->new('+inf'); ok ($x,'inf'); ok ($x->$n(), 'inf'); ok ($x->$d(),'1'); | |
82 | $x = $cr->new('-inf'); ok ($x,'-inf'); ok ($x->$n(), '-inf'); ok ($x->$d(),'1'); | |
83 | $x = $cr->new('123a4'); ok ($x,'NaN'); ok ($x->$n(), 'NaN'); ok ($x->$d(),'NaN'); | |
a4e2b1c6 JH |
84 | |
85 | # wrong inputs | |
12fc2493 AMS |
86 | $x = $cr->new('1e2e2'); ok ($x,'NaN'); ok ($x->$n(), 'NaN'); ok ($x->$d(),'NaN'); |
87 | $x = $cr->new('1+2+2'); ok ($x,'NaN'); ok ($x->$n(), 'NaN'); ok ($x->$d(),'NaN'); | |
88 | # failed due to BigFloat bug | |
89 | $x = $cr->new('1.2.2'); ok ($x,'NaN'); ok ($x->$n(), 'NaN'); ok ($x->$d(),'NaN'); | |
a4e2b1c6 JH |
90 | |
91 | ok ($cr->new('123a4'),'NaN'); | |
92 | ok ($cr->new('123e4'),'1230000'); | |
93 | ok ($cr->new('-NaN'),'NaN'); | |
94 | ok ($cr->new('NaN'),'NaN'); | |
95 | ok ($cr->new('+inf'),'inf'); | |
96 | ok ($cr->new('-inf'),'-inf'); | |
8f675a64 JH |
97 | |
98 | ############################################################################## | |
b68b7ab1 T |
99 | # two Bigints |
100 | ||
101 | ok ($cr->new($mbi->new(3),$mbi->new(7))->badd(1),'10/7'); | |
102 | ok ($cr->new($mbi->new(-13),$mbi->new(7)),'-13/7'); | |
103 | ok ($cr->new($mbi->new(13),$mbi->new(-7)),'-13/7'); | |
104 | ok ($cr->new($mbi->new(-13),$mbi->new(-7)),'13/7'); | |
105 | ||
106 | ############################################################################## | |
8f675a64 JH |
107 | # mixed arguments |
108 | ||
a4e2b1c6 JH |
109 | ok ($cr->new('3/7')->badd(1),'10/7'); |
110 | ok ($cr->new('3/10')->badd(1.1),'7/5'); | |
111 | ok ($cr->new('3/7')->badd($mbi->new(1)),'10/7'); | |
112 | ok ($cr->new('3/10')->badd($mbf->new('1.1')),'7/5'); | |
8f675a64 | 113 | |
a4e2b1c6 JH |
114 | ok ($cr->new('3/7')->bsub(1),'-4/7'); |
115 | ok ($cr->new('3/10')->bsub(1.1),'-4/5'); | |
116 | ok ($cr->new('3/7')->bsub($mbi->new(1)),'-4/7'); | |
117 | ok ($cr->new('3/10')->bsub($mbf->new('1.1')),'-4/5'); | |
8f675a64 | 118 | |
a4e2b1c6 JH |
119 | ok ($cr->new('3/7')->bmul(1),'3/7'); |
120 | ok ($cr->new('3/10')->bmul(1.1),'33/100'); | |
121 | ok ($cr->new('3/7')->bmul($mbi->new(1)),'3/7'); | |
122 | ok ($cr->new('3/10')->bmul($mbf->new('1.1')),'33/100'); | |
8f675a64 | 123 | |
a4e2b1c6 JH |
124 | ok ($cr->new('3/7')->bdiv(1),'3/7'); |
125 | ok ($cr->new('3/10')->bdiv(1.1),'3/11'); | |
126 | ok ($cr->new('3/7')->bdiv($mbi->new(1)),'3/7'); | |
127 | ok ($cr->new('3/10')->bdiv($mbf->new('1.1')),'3/11'); | |
8f675a64 JH |
128 | |
129 | ############################################################################## | |
a4e2b1c6 | 130 | $x = $cr->new('1/4'); $y = $cr->new('1/3'); |
9b924220 | 131 | |
184f15d5 JH |
132 | ok ($x + $y, '7/12'); |
133 | ok ($x * $y, '1/12'); | |
134 | ok ($x / $y, '3/4'); | |
135 | ||
a4e2b1c6 | 136 | $x = $cr->new('7/5'); $x *= '3/2'; |
184f15d5 JH |
137 | ok ($x,'21/10'); |
138 | $x -= '0.1'; | |
139 | ok ($x,'2'); # not 21/10 | |
140 | ||
a4e2b1c6 | 141 | $x = $cr->new('2/3'); $y = $cr->new('3/2'); |
184f15d5 JH |
142 | ok ($x > $y,''); |
143 | ok ($x < $y,1); | |
144 | ok ($x == $y,''); | |
145 | ||
a4e2b1c6 | 146 | $x = $cr->new('-2/3'); $y = $cr->new('3/2'); |
184f15d5 JH |
147 | ok ($x > $y,''); |
148 | ok ($x < $y,'1'); | |
149 | ok ($x == $y,''); | |
150 | ||
a4e2b1c6 | 151 | $x = $cr->new('-2/3'); $y = $cr->new('-2/3'); |
184f15d5 JH |
152 | ok ($x > $y,''); |
153 | ok ($x < $y,''); | |
154 | ok ($x == $y,'1'); | |
155 | ||
a4e2b1c6 | 156 | $x = $cr->new('-2/3'); $y = $cr->new('-1/3'); |
184f15d5 JH |
157 | ok ($x > $y,''); |
158 | ok ($x < $y,'1'); | |
159 | ok ($x == $y,''); | |
160 | ||
a4e2b1c6 | 161 | $x = $cr->new('-124'); $y = $cr->new('-122'); |
184f15d5 JH |
162 | ok ($x->bacmp($y),1); |
163 | ||
a4e2b1c6 | 164 | $x = $cr->new('-124'); $y = $cr->new('-122'); |
184f15d5 JH |
165 | ok ($x->bcmp($y),-1); |
166 | ||
a4e2b1c6 | 167 | $x = $cr->new('3/7'); $y = $cr->new('5/7'); |
8f675a64 JH |
168 | ok ($x+$y,'8/7'); |
169 | ||
a4e2b1c6 | 170 | $x = $cr->new('3/7'); $y = $cr->new('5/7'); |
8f675a64 JH |
171 | ok ($x*$y,'15/49'); |
172 | ||
a4e2b1c6 | 173 | $x = $cr->new('3/5'); $y = $cr->new('5/7'); |
8f675a64 JH |
174 | ok ($x*$y,'3/7'); |
175 | ||
a4e2b1c6 | 176 | $x = $cr->new('3/5'); $y = $cr->new('5/7'); |
8f675a64 JH |
177 | ok ($x/$y,'21/25'); |
178 | ||
93c87d9d T |
179 | $x = $cr->new('7/4'); $y = $cr->new('1'); |
180 | ok ($x % $y,'3/4'); | |
181 | ||
182 | $x = $cr->new('7/4'); $y = $cr->new('5/13'); | |
183 | ok ($x % $y,'11/52'); | |
184 | ||
185 | $x = $cr->new('7/4'); $y = $cr->new('5/9'); | |
186 | ok ($x % $y,'1/12'); | |
187 | ||
a4e2b1c6 JH |
188 | $x = $cr->new('-144/9')->bsqrt(); ok ($x,'NaN'); |
189 | $x = $cr->new('144/9')->bsqrt(); ok ($x,'4'); | |
93c87d9d T |
190 | $x = $cr->new('3/4')->bsqrt(); ok ($x, |
191 | '1732050807568877293527446341505872366943/' | |
192 | .'2000000000000000000000000000000000000000'); | |
184f15d5 | 193 | |
a4e2b1c6 JH |
194 | ############################################################################## |
195 | # bpow | |
196 | ||
197 | $x = $cr->new('2/1'); $z = $x->bpow('3/1'); ok ($x,'8'); | |
7d341013 T |
198 | $x = $cr->new('1/2'); $z = $x->bpow('3/1'); ok ($x,'1/8'); |
199 | $x = $cr->new('1/3'); $z = $x->bpow('4/1'); ok ($x,'1/81'); | |
200 | $x = $cr->new('2/3'); $z = $x->bpow('4/1'); ok ($x,'16/81'); | |
201 | ||
4de3d162 T |
202 | $x = $cr->new('2/3'); $z = $x->bpow('5/3'); |
203 | ok ($x, '31797617848703662994667839220546583581/62500000000000000000000000000000000000'); | |
a4e2b1c6 JH |
204 | |
205 | ############################################################################## | |
206 | # bfac | |
207 | ||
208 | $x = $cr->new('1'); $x->bfac(); ok ($x,'1'); | |
209 | for (my $i = 0; $i < 8; $i++) | |
210 | { | |
211 | $x = $cr->new("$i/1")->bfac(); ok ($x,$mbi->new($i)->bfac()); | |
212 | } | |
213 | ||
214 | # test for $self->bnan() vs. $x->bnan(); | |
215 | $x = $cr->new('-1'); $x->bfac(); ok ($x,'NaN'); | |
216 | ||
217 | ############################################################################## | |
218 | # binc/bdec | |
219 | ||
220 | $x = $cr->new('3/2'); ok ($x->binc(),'5/2'); | |
221 | $x = $cr->new('15/6'); ok ($x->bdec(),'3/2'); | |
222 | ||
223 | ############################################################################## | |
224 | # bfloor/bceil | |
225 | ||
12fc2493 AMS |
226 | $x = $cr->new('-7/7'); ok ($x->$n(), '-1'); ok ($x->$d(), '1'); |
227 | $x = $cr->new('-7/7')->bfloor(); ok ($x->$n(), '-1'); ok ($x->$d(), '1'); | |
a4e2b1c6 JH |
228 | |
229 | ############################################################################## | |
7d341013 T |
230 | # bsstr |
231 | ||
232 | $x = $cr->new('7/5')->bsstr(); ok ($x,'7/5'); | |
233 | $x = $cr->new('-7/5')->bsstr(); ok ($x,'-7/5'); | |
234 | ||
235 | ############################################################################## | |
236 | # numify() | |
237 | ||
238 | my @array = qw/1 2 3 4 5 6 7 8 9/; | |
239 | $x = $cr->new('8/8'); ok ($array[$x],2); | |
240 | $x = $cr->new('16/8'); ok ($array[$x],3); | |
241 | $x = $cr->new('17/8'); ok ($array[$x],3); | |
242 | $x = $cr->new('33/8'); ok ($array[$x],5); | |
243 | $x = $cr->new('-33/8'); ok ($array[$x],6); | |
b68b7ab1 | 244 | $x = $cr->new('-8/1'); ok ($array[$x],2); # -8 => 2 |
7d341013 T |
245 | |
246 | $x = $cr->new('33/8'); ok ($x->numify() * 1000, 4125); | |
247 | $x = $cr->new('-33/8'); ok ($x->numify() * 1000, -4125); | |
248 | $x = $cr->new('inf'); ok ($x->numify(), 'inf'); | |
249 | $x = $cr->new('-inf'); ok ($x->numify(), '-inf'); | |
250 | $x = $cr->new('NaN'); ok ($x->numify(), 'NaN'); | |
251 | ||
93c87d9d T |
252 | $x = $cr->new('4/3'); ok ($x->numify(), 4/3); |
253 | ||
7d341013 | 254 | ############################################################################## |
b8884ce4 | 255 | # as_hex(), as_bin(), as_oct() |
12fc2493 AMS |
256 | |
257 | $x = $cr->new('8/8'); | |
b8884ce4 | 258 | ok ($x->as_hex(), '0x1'); ok ($x->as_bin(), '0b1'); ok ($x->as_oct(), '01'); |
12fc2493 | 259 | $x = $cr->new('80/8'); |
b8884ce4 | 260 | ok ($x->as_hex(), '0xa'); ok ($x->as_bin(), '0b1010'); ok ($x->as_oct(), '012'); |
12fc2493 AMS |
261 | |
262 | ############################################################################## | |
263 | # broot(), blog(), bmodpow() and bmodinv() | |
7afd7a91 T |
264 | |
265 | $x = $cr->new(2) ** 32; | |
266 | $y = $cr->new(4); | |
267 | $z = $cr->new(3); | |
268 | ||
269 | ok ($x->copy()->broot($y), 2 ** 8); | |
270 | ok (ref($x->copy()->broot($y)), $cr); | |
271 | ||
272 | ok ($x->copy()->bmodpow($y,$z), 1); | |
273 | ok (ref($x->copy()->bmodpow($y,$z)), $cr); | |
274 | ||
275 | $x = $cr->new(8); | |
276 | $y = $cr->new(5033); | |
277 | $z = $cr->new(4404); | |
278 | ||
279 | ok ($x->copy()->bmodinv($y), $z); | |
280 | ok (ref($x->copy()->bmodinv($y)), $cr); | |
281 | ||
9b924220 RGS |
282 | # square root with exact result |
283 | $x = $cr->new('1.44'); | |
4de3d162 | 284 | ok ($x->copy()->broot(2), '6/5'); |
9b924220 RGS |
285 | ok (ref($x->copy()->broot(2)), $cr); |
286 | ||
287 | # log with exact result | |
288 | $x = $cr->new('256.1'); | |
289 | ok ($x->copy()->blog(2), '8000563442710106079310294693803606983661/1000000000000000000000000000000000000000'); | |
290 | ok (ref($x->copy()->blog(2)), $cr); | |
291 | ||
12fc2493 AMS |
292 | $x = $cr->new(144); |
293 | ok ($x->copy()->broot('2'), 12, 'v/144 = 12'); | |
294 | ||
295 | $x = $cr->new(12*12*12); | |
296 | ok ($x->copy()->broot('3'), 12, '(12*12*12) ** 1/3 = 12'); | |
9b924220 | 297 | |
7afd7a91 | 298 | ############################################################################## |
b8884ce4 T |
299 | # from_hex(), from_bin(), from_oct() |
300 | ||
301 | $x = Math::BigRat->from_hex('0x100'); | |
302 | ok ($x, '256', 'from_hex'); | |
303 | $x = $cr->from_hex('0x100'); | |
304 | ok ($x, '256', 'from_hex'); | |
305 | ||
306 | $x = Math::BigRat->from_bin('0b100'); | |
307 | ok ($x, '4', 'from_bin'); | |
308 | $x = $cr->from_bin('0b100'); | |
309 | ok ($x, '4', 'from_bin'); | |
310 | ||
311 | $x = Math::BigRat->from_oct('0100'); | |
312 | ok ($x, '64', 'from_oct'); | |
313 | $x = $cr->from_oct('0100'); | |
314 | ok ($x, '64', 'from_oct'); | |
315 | ||
316 | ############################################################################## | |
4de3d162 T |
317 | # as_float() |
318 | ||
319 | $x = Math::BigRat->new('1/2'); my $f = $x->as_float(); | |
320 | ||
321 | ok ($x, '1/2', '$x unmodified'); | |
322 | ok ($f, '0.5', 'as_float(0.5)'); | |
323 | ||
324 | $x = Math::BigRat->new('2/3'); $f = $x->as_float(5); | |
325 | ||
326 | ok ($x, '2/3', '$x unmodified'); | |
327 | ok ($f, '0.66667', 'as_float(2/3,5)'); | |
328 | ||
329 | ############################################################################## | |
184f15d5 JH |
330 | # done |
331 | ||
332 | 1; | |
333 |