This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Sync Math::BigRat with CPAN 0.2624
[perl5.git] / cpan / Math-BigRat / t / bigrat.t
CommitLineData
6853e8af 1# -*- mode: perl; -*-
184f15d5
JH
2
3use strict;
11c955be
SH
4use warnings;
5
e59cb199 6use Test::More tests => 203;
184f15d5 7
12fc2493 8# basic testing of Math::BigRat
184f15d5
JH
9
10use Math::BigRat;
6de7f0cc
JH
11use Math::BigInt;
12use Math::BigFloat;
13
14# shortcuts
11c955be 15my $mbr = 'Math::BigRat';
6de7f0cc
JH
16my $mbi = 'Math::BigInt';
17my $mbf = 'Math::BigFloat';
184f15d5 18
11c955be 19my ($x, $y, $z);
184f15d5 20
11c955be 21$x = Math::BigRat->new(1234);
d18b40da 22is($x, 1234, 'value of $x');
11c955be 23isa_ok($x, 'Math::BigRat');
d18b40da
N
24ok(!$x->isa('Math::BigInt'),
25 "An object of class '" . ref($x) . "' isn't a 'Math::BigInt'");
26ok(!$x->isa('Math::BigFloat'),
27 "An object of class '" . ref($x) . "' isn't a 'Math::BigFloat'");
8f675a64
JH
28
29##############################################################################
6de7f0cc 30# new and bnorm()
8f675a64 31
d18b40da
N
32foreach my $method (qw/ new bnorm /) {
33 $x = $mbr->$method(1234);
34 is($x, 1234, qq|\$x = $mbr->$method(1234)|);
c32198f6 35
d18b40da
N
36 $x = $mbr->$method("1234/1");
37 is($x, 1234, qq|\$x = $mbr->$method("1234/1")|);
c32198f6 38
d18b40da
N
39 $x = $mbr->$method("1234/2");
40 is($x, 617, qq|\$x = $mbr->$method("1234/2")|);
c32198f6 41
d18b40da
N
42 $x = $mbr->$method("100/1.0");
43 is($x, 100, qq|\$x = $mbr->$method("100/1.0")|);
c6c613ed 44
d18b40da
N
45 $x = $mbr->$method("10.0/1.0");
46 is($x, 10, qq|\$x = $mbr->$method("10.0/1.0")|);
ccbfef19 47
d18b40da
N
48 $x = $mbr->$method("0.1/10");
49 is($x, "1/100", qq|\$x = $mbr->$method("0.1/10")|);
6de7f0cc 50
d18b40da
N
51 $x = $mbr->$method("0.1/0.1");
52 is($x, "1", qq|\$x = $mbr->$method("0.1/0.1")|);
6de7f0cc 53
d18b40da
N
54 $x = $mbr->$method("1e2/10");
55 is($x, 10, qq|\$x = $mbr->$method("1e2/10")|);
9b924220 56
d18b40da
N
57 $x = $mbr->$method("5/1e2");
58 is($x, "1/20", qq|\$x = $mbr->$method("5/1e2")|);
a4e2b1c6 59
d18b40da
N
60 $x = $mbr->$method("1e2/1e1");
61 is($x, 10, qq|\$x = $mbr->$method("1e2/1e1")|);
12fc2493 62
d18b40da
N
63 $x = $mbr->$method("1 / 3");
64 is($x, "1/3", qq|\$x = $mbr->$method("1 / 3")|);
a4e2b1c6 65
d18b40da
N
66 $x = $mbr->$method("-1 / 3");
67 is($x, "-1/3", qq|\$x = $mbr->$method("-1 / 3")|);
a4e2b1c6 68
d18b40da
N
69 $x = $mbr->$method("NaN");
70 is($x, "NaN", qq|\$x = $mbr->$method("NaN")|);
8f675a64 71
d18b40da
N
72 $x = $mbr->$method("inf");
73 is($x, "inf", qq|\$x = $mbr->$method("inf")|);
b68b7ab1 74
d18b40da
N
75 $x = $mbr->$method("-inf");
76 is($x, "-inf", qq|\$x = $mbr->$method("-inf")|);
b68b7ab1 77
d18b40da
N
78 $x = $mbr->$method("1/");
79 is($x, "NaN", qq|\$x = $mbr->$method("1/")|);
8f675a64 80
d18b40da
N
81 $x = $mbr->$method("0x7e");
82 is($x, 126, qq|\$x = $mbr->$method("0x7e")|);
8f675a64 83
11c955be 84 # input ala "1+1/3" isn"t parsed ok yet
d18b40da
N
85 $x = $mbr->$method("1+1/3");
86 is($x, "NaN", qq|\$x = $mbr->$method("1+1/3")|);
8f675a64 87
d18b40da
N
88 $x = $mbr->$method("1/1.2");
89 is($x, "5/6", qq|\$x = $mbr->$method("1/1.2")|);
8f675a64 90
d18b40da
N
91 $x = $mbr->$method("1.3/1.2");
92 is($x, "13/12", qq|\$x = $mbr->$method("1.3/1.2")|);
8f675a64 93
d18b40da
N
94 $x = $mbr->$method("1.2/1");
95 is($x, "6/5", qq|\$x = $mbr->$method("1.2/1")|);
9b924220 96
11c955be
SH
97 ############################################################################
98 # other classes as input
184f15d5 99
d18b40da
N
100 $x = $mbr->$method($mbi->new(1231));
101 is($x, "1231", qq|\$x = $mbr->$method($mbi->new(1231))|);
11c955be 102
d18b40da
N
103 $x = $mbr->$method($mbf->new(1232));
104 is($x, "1232", qq|\$x = $mbr->$method($mbf->new(1232))|);
184f15d5 105
d18b40da
N
106 $x = $mbr->$method($mbf->new(1232.3));
107 is($x, "12323/10", qq|\$x = $mbr->$method($mbf->new(1232.3))|);
11c955be 108}
184f15d5 109
11c955be
SH
110my $n = 'numerator';
111my $d = 'denominator';
112
6320cdc0 113$x = $mbr->new('-0');
11c955be 114is($x, '0');
6320cdc0 115is($x->$n(), '0');
11c955be
SH
116is($x->$d(), '1');
117
6320cdc0 118$x = $mbr->new('NaN');
11c955be
SH
119is($x, 'NaN'); is($x->$n(), 'NaN');
120is($x->$d(), 'NaN');
121
6320cdc0 122$x = $mbr->new('-NaN');
11c955be
SH
123is($x, 'NaN'); is($x->$n(), 'NaN');
124is($x->$d(), 'NaN');
125
6320cdc0 126$x = $mbr->new('-1r4');
11c955be
SH
127is($x, 'NaN'); is($x->$n(), 'NaN');
128is($x->$d(), 'NaN');
184f15d5 129
6320cdc0 130$x = $mbr->new('+inf');
11c955be
SH
131is($x, 'inf'); is($x->$n(), 'inf');
132is($x->$d(), '1');
184f15d5 133
6320cdc0 134$x = $mbr->new('-inf');
11c955be
SH
135is($x, '-inf');
136is($x->$n(), '-inf');
137is($x->$d(), '1');
138
6320cdc0 139$x = $mbr->new('123a4');
11c955be
SH
140is($x, 'NaN');
141is($x->$n(), 'NaN');
142is($x->$d(), 'NaN');
143
144# wrong inputs
6320cdc0 145$x = $mbr->new('1e2e2');
11c955be
SH
146is($x, 'NaN');
147is($x->$n(), 'NaN');
148is($x->$d(), 'NaN');
149
6320cdc0 150$x = $mbr->new('1+2+2');
11c955be
SH
151is($x, 'NaN');
152is($x->$n(), 'NaN');
153is($x->$d(), 'NaN');
154
155# failed due to BigFloat bug
6320cdc0 156$x = $mbr->new('1.2.2');
11c955be
SH
157is($x, 'NaN');
158is($x->$n(), 'NaN');
159is($x->$d(), 'NaN');
160
161is($mbr->new('123a4'), 'NaN');
162is($mbr->new('123e4'), '1230000');
163is($mbr->new('-NaN'), 'NaN');
164is($mbr->new('NaN'), 'NaN');
165is($mbr->new('+inf'), 'inf');
166is($mbr->new('-inf'), '-inf');
184f15d5 167
11c955be
SH
168##############################################################################
169# two Bigints
184f15d5 170
11c955be
SH
171is($mbr->new($mbi->new(3), $mbi->new(7))->badd(1), '10/7');
172is($mbr->new($mbi->new(-13), $mbi->new(7)), '-13/7');
173is($mbr->new($mbi->new(13), $mbi->new(-7)), '-13/7');
174is($mbr->new($mbi->new(-13), $mbi->new(-7)), '13/7');
184f15d5 175
11c955be
SH
176##############################################################################
177# mixed arguments
8f675a64 178
11c955be
SH
179is($mbr->new('3/7')->badd(1), '10/7');
180is($mbr->new('3/10')->badd(1.1), '7/5');
181is($mbr->new('3/7')->badd($mbi->new(1)), '10/7');
182is($mbr->new('3/10')->badd($mbf->new('1.1')), '7/5');
8f675a64 183
11c955be
SH
184is($mbr->new('3/7')->bsub(1), '-4/7');
185is($mbr->new('3/10')->bsub(1.1), '-4/5');
186is($mbr->new('3/7')->bsub($mbi->new(1)), '-4/7');
187is($mbr->new('3/10')->bsub($mbf->new('1.1')), '-4/5');
8f675a64 188
11c955be
SH
189is($mbr->new('3/7')->bmul(1), '3/7');
190is($mbr->new('3/10')->bmul(1.1), '33/100');
191is($mbr->new('3/7')->bmul($mbi->new(1)), '3/7');
192is($mbr->new('3/10')->bmul($mbf->new('1.1')), '33/100');
8f675a64 193
11c955be
SH
194is($mbr->new('3/7')->bdiv(1), '3/7');
195is($mbr->new('3/10')->bdiv(1.1), '3/11');
196is($mbr->new('3/7')->bdiv($mbi->new(1)), '3/7');
197is($mbr->new('3/10')->bdiv($mbf->new('1.1')), '3/11');
93c87d9d 198
11c955be
SH
199##############################################################################
200$x = $mbr->new('1/4');
201$y = $mbr->new('1/3');
93c87d9d 202
11c955be
SH
203is($x + $y, '7/12');
204is($x * $y, '1/12');
205is($x / $y, '3/4');
93c87d9d 206
11c955be
SH
207$x = $mbr->new('7/5');
208$x *= '3/2';
209is($x, '21/10');
210$x -= '0.1';
211is($x, '2'); # not 21/10
212
213$x = $mbr->new('2/3');
214$y = $mbr->new('3/2');
215is($x > $y, '');
216is($x < $y, 1);
217is($x == $y, '');
218
219$x = $mbr->new('-2/3');
220$y = $mbr->new('3/2');
221is($x > $y, '');
222is($x < $y, '1');
223is($x == $y, '');
224
225$x = $mbr->new('-2/3');
226$y = $mbr->new('-2/3');
227is($x > $y, '');
228is($x < $y, '');
229is($x == $y, '1');
230
231$x = $mbr->new('-2/3');
232$y = $mbr->new('-1/3');
233is($x > $y, '');
234is($x < $y, '1');
235is($x == $y, '');
236
237$x = $mbr->new('-124');
238$y = $mbr->new('-122');
239is($x->bacmp($y), 1);
240
241$x = $mbr->new('-124');
242$y = $mbr->new('-122');
243is($x->bcmp($y), -1);
244
245$x = $mbr->new('3/7');
246$y = $mbr->new('5/7');
247is($x+$y, '8/7');
248
249$x = $mbr->new('3/7');
250$y = $mbr->new('5/7');
251is($x*$y, '15/49');
252
253$x = $mbr->new('3/5');
254$y = $mbr->new('5/7');
255is($x*$y, '3/7');
256
257$x = $mbr->new('3/5');
258$y = $mbr->new('5/7');
259is($x/$y, '21/25');
260
261$x = $mbr->new('7/4');
262$y = $mbr->new('1');
263is($x % $y, '3/4');
264
265$x = $mbr->new('7/4');
266$y = $mbr->new('5/13');
267is($x % $y, '11/52');
268
269$x = $mbr->new('7/4');
270$y = $mbr->new('5/9');
271is($x % $y, '1/12');
272
273$x = $mbr->new('-144/9')->bsqrt();
274is($x, 'NaN');
275
276$x = $mbr->new('144/9')->bsqrt();
277is($x, '4');
278
279$x = $mbr->new('3/4')->bsqrt();
280is($x,
6320cdc0
SH
281 '4330127018922193233818615853764680917357/' .
282 '5000000000000000000000000000000000000000');
184f15d5 283
a4e2b1c6
JH
284##############################################################################
285# bpow
286
11c955be
SH
287$x = $mbr->new('2/1');
288$z = $x->bpow('3/1');
289is($x, '8');
7d341013 290
11c955be
SH
291$x = $mbr->new('1/2');
292$z = $x->bpow('3/1');
293is($x, '1/8');
294
295$x = $mbr->new('1/3');
296$z = $x->bpow('4/1');
297is($x, '1/81');
298
299$x = $mbr->new('2/3');
300$z = $x->bpow('4/1');
301is($x, '16/81');
302
303$x = $mbr->new('2/3');
304$z = $x->bpow('5/3');
305is($x, '31797617848703662994667839220546583581/62500000000000000000000000000000000000');
a4e2b1c6
JH
306
307##############################################################################
308# bfac
309
11c955be
SH
310$x = $mbr->new('1');
311$x->bfac();
312is($x, '1');
313
314for (my $i = 0; $i < 8; $i++) {
315 $x = $mbr->new("$i/1")->bfac();
316 is($x, $mbi->new($i)->bfac());
317}
a4e2b1c6
JH
318
319# test for $self->bnan() vs. $x->bnan();
11c955be
SH
320$x = $mbr->new('-1');
321$x->bfac();
322is($x, 'NaN');
a4e2b1c6
JH
323
324##############################################################################
325# binc/bdec
326
d18b40da 327note("binc()");
11c955be
SH
328$x = $mbr->new('3/2');
329is($x->binc(), '5/2');
d18b40da
N
330
331note("bdec()");
332
11c955be
SH
333$x = $mbr->new('15/6');
334is($x->bdec(), '3/2');
a4e2b1c6
JH
335
336##############################################################################
d18b40da 337# bfloor
a4e2b1c6 338
d18b40da 339note("bfloor()");
11c955be
SH
340$x = $mbr->new('-7/7');
341is($x->$n(), '-1');
342is($x->$d(), '1');
343$x = $mbr->new('-7/7')->bfloor();
344is($x->$n(), '-1');
345is($x->$d(), '1');
a4e2b1c6
JH
346
347##############################################################################
7d341013
T
348# bsstr
349
11c955be
SH
350$x = $mbr->new('7/5')->bsstr();
351is($x, '7/5');
352$x = $mbr->new('-7/5')->bsstr();
353is($x, '-7/5');
7d341013
T
354
355##############################################################################
6853e8af
RL
356
357note("numify()");
7d341013
T
358
359my @array = qw/1 2 3 4 5 6 7 8 9/;
11c955be
SH
360$x = $mbr->new('8/8');
361is($array[$x], 2);
362
363$x = $mbr->new('16/8');
364is($array[$x], 3);
365
366$x = $mbr->new('17/8');
367is($array[$x], 3);
7d341013 368
11c955be
SH
369$x = $mbr->new('33/8');
370is($array[$x], 5);
7d341013 371
11c955be
SH
372$x = $mbr->new('-33/8');
373is($array[$x], 6);
374
375$x = $mbr->new('-8/1');
376is($array[$x], 2); # -8 => 2
377
6853e8af 378require Math::Complex;
11c955be 379
6853e8af
RL
380my $inf = $Math::Complex::Inf;
381my $nan = $inf - $inf;
11c955be 382
6853e8af
RL
383sub isnumeric {
384 my $value = shift;
385 ($value ^ $value) eq "0";
386}
11c955be 387
6853e8af
RL
388subtest qq|$mbr -> new("33/8") -> numify()| => sub {
389 plan tests => 3;
390
391 $x = $mbr -> new("33/8") -> numify();
392 is(ref($x), "", '$x is a scalar');
393 ok(isnumeric($x), '$x is numeric');
394 cmp_ok($x, "==", 4.125, '$x has the right value');
395};
396
397subtest qq|$mbr -> new("-33/8") -> numify()| => sub {
398 plan tests => 3;
399
400 $x = $mbr -> new("-33/8") -> numify();
401 is(ref($x), "", '$x is a scalar');
402 ok(isnumeric($x), '$x is numeric');
403 cmp_ok($x, "==", -4.125, '$x has the right value');
404};
405
406subtest qq|$mbr -> new("inf") -> numify()| => sub {
407 plan tests => 3;
408
409 $x = $mbr -> new("inf") -> numify();
410 is(ref($x), "", '$x is a scalar');
411 ok(isnumeric($x), '$x is numeric');
412 cmp_ok($x, "==", $inf, '$x has the right value');
413};
414
415subtest qq|$mbr -> new("-inf") -> numify()| => sub {
416 plan tests => 3;
417
418 $x = $mbr -> new("-inf") -> numify();
419 is(ref($x), "", '$x is a scalar');
420 ok(isnumeric($x), '$x is numeric');
421 cmp_ok($x, "==", -$inf, '$x has the right value');
422};
423
424subtest qq|$mbr -> new("NaN") -> numify()| => sub {
425 plan tests => 3;
426
427 $x = $mbr -> new("NaN") -> numify();
428 is(ref($x), "", '$x is a scalar');
429 ok(isnumeric($x), '$x is numeric');
430 cmp_ok($x, "!=", $nan, '$x has the right value'); # Note: NaN != NaN
431};
93c87d9d 432
7d341013 433##############################################################################
b8884ce4 434# as_hex(), as_bin(), as_oct()
12fc2493 435
d18b40da
N
436note("as_hex(), as_bin(), as_oct()");
437
11c955be
SH
438$x = $mbr->new('8/8');
439is($x->as_hex(), '0x1');
440is($x->as_bin(), '0b1');
441is($x->as_oct(), '01');
442
443$x = $mbr->new('80/8');
444is($x->as_hex(), '0xa');
445is($x->as_bin(), '0b1010');
446is($x->as_oct(), '012');
12fc2493
AMS
447
448##############################################################################
449# broot(), blog(), bmodpow() and bmodinv()
7afd7a91 450
d18b40da
N
451note("broot(), blog(), bmodpow(), bmodinv()");
452
11c955be
SH
453$x = $mbr->new(2) ** 32;
454$y = $mbr->new(4);
455$z = $mbr->new(3);
7afd7a91 456
11c955be 457is($x->copy()->broot($y), 2 ** 8);
d18b40da 458is(ref($x->copy()->broot($y)), $mbr, "\$x is a $mbr");
7afd7a91 459
11c955be 460is($x->copy()->bmodpow($y, $z), 1);
d18b40da 461is(ref($x->copy()->bmodpow($y, $z)), $mbr, "\$x is a $mbr");
7afd7a91 462
11c955be
SH
463$x = $mbr->new(8);
464$y = $mbr->new(5033);
465$z = $mbr->new(4404);
7afd7a91 466
11c955be 467is($x->copy()->bmodinv($y), $z);
d18b40da 468is(ref($x->copy()->bmodinv($y)), $mbr, "\$x is a $mbr");
7afd7a91 469
9b924220 470# square root with exact result
11c955be
SH
471$x = $mbr->new('1.44');
472is($x->copy()->broot(2), '6/5');
d18b40da 473is(ref($x->copy()->broot(2)), $mbr, "\$x is a $mbr");
9b924220
RGS
474
475# log with exact result
11c955be 476$x = $mbr->new('256.1');
d18b40da
N
477is($x->copy()->blog(2),
478 '8000563442710106079310294693803606983661/1000000000000000000000000000000000000000',
479 "\$x = $mbr->new('256.1')->blog(2)");
480is(ref($x->copy()->blog(2)), $mbr, "\$x is a $mbr");
9b924220 481
11c955be
SH
482$x = $mbr->new(144);
483is($x->copy()->broot('2'), 12, 'v/144 = 12');
12fc2493 484
11c955be
SH
485$x = $mbr->new(12*12*12);
486is($x->copy()->broot('3'), 12, '(12*12*12) ** 1/3 = 12');
9b924220 487
7afd7a91 488##############################################################################
b8884ce4
T
489# from_hex(), from_bin(), from_oct()
490
d18b40da
N
491note("from_hex(), from_bin(), from_oct()");
492
b8884ce4 493$x = Math::BigRat->from_hex('0x100');
11c955be
SH
494is($x, '256', 'from_hex');
495
496$x = $mbr->from_hex('0x100');
497is($x, '256', 'from_hex');
b8884ce4
T
498
499$x = Math::BigRat->from_bin('0b100');
11c955be
SH
500is($x, '4', 'from_bin');
501
502$x = $mbr->from_bin('0b100');
503is($x, '4', 'from_bin');
b8884ce4
T
504
505$x = Math::BigRat->from_oct('0100');
11c955be
SH
506is($x, '64', 'from_oct');
507
508$x = $mbr->from_oct('0100');
509is($x, '64', 'from_oct');
b8884ce4
T
510
511##############################################################################
4de3d162
T
512# as_float()
513
11c955be
SH
514$x = Math::BigRat->new('1/2');
515my $f = $x->as_float();
4de3d162 516
11c955be
SH
517is($x, '1/2', '$x unmodified');
518is($f, '0.5', 'as_float(0.5)');
4de3d162 519
11c955be
SH
520$x = Math::BigRat->new('2/3');
521$f = $x->as_float(5);
4de3d162 522
11c955be
SH
523is($x, '2/3', '$x unmodified');
524is($f, '0.66667', 'as_float(2/3, 5)');
4de3d162 525
e59cb199
HS
526# Integers should be converted exactly.
527$x = Math::BigRat->new("3141592653589793238462643383279502884197169399375106");
528$f = $x->as_float();
529
530is($x, "3141592653589793238462643383279502884197169399375106", '$x unmodified');
531is($f, "3141592653589793238462643383279502884197169399375106",
532 'as_float(3141592653589793238462643383279502884197169399375106, 5)');
533
4de3d162 534##############################################################################
d93f0209
FC
535# int()
536
11c955be
SH
537$x = Math::BigRat->new('5/2');
538is(int($x), '2', '5/2 converted to integer');
539
540$x = Math::BigRat->new('-1/2');
541is(int($x), '0', '-1/2 converted to integer');
d93f0209
FC
542
543##############################################################################
184f15d5
JH
544# done
545
5461;