1# -*- mode: perl; -*-
2
3# Note that this does not test Math::BigRat upgrading.
4
5use strict;
6use warnings;
7
8use Test::More tests => 141;
9
10use Math::BigInt upgrade   => 'Math::BigRat';
11use Math::BigRat downgrade => 'Math::BigInt';
12
13is(Math::BigRat->downgrade(), 'Math::BigInt', 'Math::BigRat->downgrade()');
14is(Math::BigInt->upgrade(),   'Math::BigRat', 'Math::BigInt->upgrade()');
15
16################################################################################
17# Verify that constructors downgrade when they should.
18
19note("Enable downgrading, and see if constructors downgrade");
20
21my $x;
22
23# new()
24
25$x = Math::BigRat -> new("0.5");
26cmp_ok($x, "==", 0.5);
27is(ref $x, "Math::BigRat", "Creating a 0.5 does not downgrade");
28
29$x = Math::BigRat -> new("4");
30cmp_ok($x, "==", 4, 'new("4")');
31is(ref $x, "Math::BigInt", "Creating a 4 downgrades to Math::BigInt");
32
33$x = Math::BigRat -> new("0");
34cmp_ok($x, "==", 0, 'new("0")');
35is(ref $x, "Math::BigInt", "Creating a 0 downgrades to Math::BigInt");
36
37$x = Math::BigRat -> new("1");
38cmp_ok($x, "==", 1, 'new("1")');
39is(ref $x, "Math::BigInt", "Creating a 1 downgrades to Math::BigInt");
40
41$x = Math::BigRat -> new("Inf");
42cmp_ok($x, "==", "Inf", 'new("inf")');
43is(ref $x, "Math::BigInt", "Creating an Inf downgrades to Math::BigInt");
44
45$x = Math::BigRat -> new("NaN");
46is($x, "NaN", 'new("NaN")');
47is(ref $x, "Math::BigInt", "Creating a NaN downgrades to Math::BigInt");
48
49# bzero()
50
51$x = Math::BigRat -> bzero();
52cmp_ok($x, "==", 0, "bzero()");
53is(ref $x, "Math::BigInt", "Creating a 0 downgrades to Math::BigInt");
54
55# bone()
56
57$x = Math::BigRat -> bone();
58cmp_ok($x, "==", 1, "bone()");
59is(ref $x, "Math::BigInt", "Creating a 1 downgrades to Math::BigInt");
60
61# binf()
62
63$x = Math::BigRat -> binf();
64cmp_ok($x, "==", "Inf", "binf()");
65is(ref $x, "Math::BigInt", "Creating an Inf downgrades to Math::BigInt");
66
67# bnan()
68
69$x = Math::BigRat -> bnan();
70is($x, "NaN", "bnan()");
71is(ref $x, "Math::BigInt", "Creating a NaN downgrades to Math::BigInt");
72
73# from_hex()
74
75$x = Math::BigRat -> from_hex("13a");
76cmp_ok($x, "==", 314, 'from_hex("13a")');
77is(ref $x, "Math::BigInt", 'from_hex("13a") downgrades to Math::BigInt');
78
79# from_oct()
80
81$x = Math::BigRat -> from_oct("472");
82cmp_ok($x, "==", 314, 'from_oct("472")');
83is(ref $x, "Math::BigInt", 'from_oct("472") downgrades to Math::BigInt');
84
85# from_bin()
86
87$x = Math::BigRat -> from_bin("100111010");
88cmp_ok($x, "==", 314, 'from_bin("100111010")');
89is(ref $x, "Math::BigInt",
90   'from_bin("100111010") downgrades to Math::BigInt');
91
92note("Disable downgrading, and see if constructors downgrade");
93
94Math::BigRat -> downgrade(undef);
95
96my $half = Math::BigRat -> new("1/2");
97my $four = Math::BigRat -> new("4");
98my $zero = Math::BigRat -> bzero();
99my $inf  = Math::BigRat -> binf();
100my $nan  = Math::BigRat -> bnan();
101
102is(ref $half, "Math::BigRat", "Creating a 0.5 does not downgrade");
103is(ref $four, "Math::BigRat", "Creating a 4 does not downgrade");
104is(ref $zero, "Math::BigRat", "Creating a 0 does not downgrade");
105is(ref $inf,  "Math::BigRat", "Creating an Inf does not downgrade");
106is(ref $nan,  "Math::BigRat", "Creating a NaN does not downgrade");
107
108################################################################################
109# Verify that other methods downgrade when they should.
110
111Math::BigRat -> downgrade("Math::BigInt");
112
113note("bneg()");
114
115$x = $zero -> copy() -> bneg();
116cmp_ok($x, "==", 0, "-(0) = 0");
117is(ref($x), "Math::BigInt", "-(0) => Math::BigInt");
118
119$x = $four -> copy() -> bneg();
120cmp_ok($x, "==", -4, "-(4) = -4");
121is(ref($x), "Math::BigInt", "-(4) => Math::BigInt");
122
123$x = $inf -> copy() -> bneg();
124cmp_ok($x, "==", "-inf", "-(Inf) = -Inf");
125is(ref($x), "Math::BigInt", "-(Inf) => Math::BigInt");
126
127$x = $nan -> copy() -> bneg();
128is($x, "NaN", "-(NaN) = NaN");
129is(ref($x), "Math::BigInt", "-(NaN) => Math::BigInt");
130
131note("bnorm()");
132
133$x = $zero -> copy() -> bnorm();
134cmp_ok($x, "==", 0, "bnorm(0)");
135is(ref($x), "Math::BigInt", "bnorm(0) => Math::BigInt");
136
137$x = $four -> copy() -> bnorm();
138cmp_ok($x, "==", 4, "bnorm(4)");
139is(ref($x), "Math::BigInt", "bnorm(4) => Math::BigInt");
140
141$x = $inf -> copy() -> bnorm();
142cmp_ok($x, "==", "inf", "bnorm(Inf)");
143is(ref($x), "Math::BigInt", "bnorm(Inf) => Math::BigInt");
144
145$x = $nan -> copy() -> bnorm();
146is($x, "NaN", "bnorm(NaN)");
147is(ref($x), "Math::BigInt", "bnorm(NaN) => Math::BigInt");
148
149note("binc()");
150
151$x = $zero -> copy() -> binc();
152cmp_ok($x, "==", 1, "binc(0)");
153is(ref($x), "Math::BigInt", "binc(0) => Math::BigInt");
154
155$x = $four -> copy() -> binc();
156cmp_ok($x, "==", 5, "binc(4)");
157is(ref($x), "Math::BigInt", "binc(4) => Math::BigInt");
158
159$x = $inf -> copy() -> binc();
160cmp_ok($x, "==", "inf", "binc(Inf)");
161is(ref($x), "Math::BigInt", "binc(Inf) => Math::BigInt");
162
163$x = $nan -> copy() -> binc();
164is($x, "NaN", "binc(NaN)");
165is(ref($x), "Math::BigInt", "binc(NaN) => Math::BigInt");
166
167note("bdec()");
168
169$x = $zero -> copy() -> bdec();
170cmp_ok($x, "==", -1, "bdec(0)");
171is(ref($x), "Math::BigInt", "bdec(0) => Math::BigInt");
172
173$x = $four -> copy() -> bdec();
174cmp_ok($x, "==", 3, "bdec(4)");
175is(ref($x), "Math::BigInt", "bdec(4) => Math::BigInt");
176
177$x = $inf -> copy() -> bdec();
178cmp_ok($x, "==", "inf", "bdec(Inf)");
179is(ref($x), "Math::BigInt", "bdec(Inf) => Math::BigInt");
180
181$x = $nan -> copy() -> bdec();
182is($x, "NaN", "bdec(NaN)");
183is(ref($x), "Math::BigInt", "bdec(NaN) => Math::BigInt");
184
185note("badd()");
186
187$x = $half -> copy() -> badd($nan);
188is($x, "NaN", "0.5 + NaN = NaN");
189is(ref($x), "Math::BigInt", "0.5 + NaN => Math::BigInt");
190
191$x = $half -> copy() -> badd($inf);
192cmp_ok($x, "==", "+Inf", "0.5 + Inf = Inf");
193is(ref($x), "Math::BigInt", "2.5 + Inf => Math::BigInt");
194
195$x = $half -> copy() -> badd($half);
196cmp_ok($x, "==", 1, "0.5 + 0.5 = 1");
197is(ref($x), "Math::BigInt", "0.5 + 0.5 => Math::BigInt");
198
199$x = $half -> copy() -> badd($half -> copy() -> bneg());
200cmp_ok($x, "==", 0, "0.5 + -0.5 = 0");
201is(ref($x), "Math::BigInt", "0.5 + -0.5 => Math::BigInt");
202
203$x = $four -> copy() -> badd($zero);
204cmp_ok($x, "==", 4, "4 + 0 = 4");
205is(ref($x), "Math::BigInt", "4 + 0 => Math::BigInt");
206
207$x = $zero -> copy() -> badd($four);
208cmp_ok($x, "==", 4, "0 + 4 = 4");
209is(ref($x), "Math::BigInt", "0 + 4 => Math::BigInt");
210
211$x = $inf -> copy() -> badd($four);
212cmp_ok($x, "==", "+Inf", "Inf + 4 = Inf");
213is(ref($x), "Math::BigInt", "Inf + 4 => Math::BigInt");
214
215$x = $nan -> copy() -> badd($four);
216is($x, "NaN", "NaN + 4 = NaN");
217is(ref($x), "Math::BigInt", "NaN + 4 => Math::BigInt");
218
219note("bsub()");
220
221$x = $half -> copy() -> bsub($nan);
222is($x, "NaN", "0.5 - NaN = NaN");
223is(ref($x), "Math::BigInt", "0.5 - NaN => Math::BigInt");
224
225$x = $half -> copy() -> bsub($inf);
226cmp_ok($x, "==", "-Inf", "2.5 - Inf = -Inf");
227is(ref($x), "Math::BigInt", "2.5 - Inf => Math::BigInt");
228
229$x = $half -> copy() -> bsub($half);
230cmp_ok($x, "==", 0, "0.5 - 0.5 = 0");
231is(ref($x), "Math::BigInt", "0.5 - 0.5 => Math::BigInt");
232
233$x = $half -> copy() -> bsub($half -> copy() -> bneg());
234cmp_ok($x, "==", 1, "0.5 - -0.5 = 1");
235is(ref($x), "Math::BigInt", "0.5 - -0.5 => Math::BigInt");
236
237$x = $four -> copy() -> bsub($zero);
238cmp_ok($x, "==", 4, "4 - 0 = 4");
239is(ref($x), "Math::BigInt", "4 - 0 => Math::BigInt");
240
241$x = $zero -> copy() -> bsub($four);
242cmp_ok($x, "==", -4, "0 - 4 = -4");
243is(ref($x), "Math::BigInt", "0 - 4 => Math::BigInt");
244
245$x = $inf -> copy() -> bsub($four);
246cmp_ok($x, "==", "Inf", "Inf - 4 = Inf");
247is(ref($x), "Math::BigInt", "Inf - 4 => Math::BigInt");
248
249$x = $nan -> copy() -> bsub($four);
250is($x, "NaN", "NaN - 4 = NaN");
251is(ref($x), "Math::BigInt", "NaN - 4 => Math::BigInt");
252
253note("bmul()");
254
255$x = $zero -> copy() -> bmul($four);
256cmp_ok($x, "==", 0, "bmul(0, 4) = 0");
257is(ref($x), "Math::BigInt", "bmul(0, 4) => Math::BigInt");
258
259$x = $four -> copy() -> bmul($four);
260cmp_ok($x, "==", 16, "bmul(4, 4) = 16");
261is(ref($x), "Math::BigInt", "bmul(4, 4) => Math::BigInt");
262
263$x = $inf -> copy() -> bmul($four);
264cmp_ok($x, "==", "inf", "bmul(Inf, 4) = Inf");
265is(ref($x), "Math::BigInt", "bmul(Inf, 4) => Math::BigInt");
266
267$x = $nan -> copy() -> bmul($four);
268is($x, "NaN", "bmul(NaN, 4) = NaN");
269is(ref($x), "Math::BigInt", "bmul(NaN, 4) => Math::BigInt");
270
271$x = $four -> copy() -> bmul("0.5");
272cmp_ok($x, "==", 2, "bmul(4, 0.5) = 2");
273is(ref($x), "Math::BigInt", "bmul(4, 0.5) => Math::BigInt");
274
275# bmuladd()
276
277note("bdiv()");
278
279note("bmod()");
280
281note("bmodpow()");
282
283note("bpow()");
284
285note("blog()");
286
287note("bexp()");
288
289note("bnok()");
290
291note("bsin()");
292
293note("bcos()");
294
295note("batan()");
296
297note("batan()");
298
299note("bsqrt()");
300
301note("broot()");
302
303note("bfac()");
304
305note("bdfac()");
306
307note("btfac()");
308
309note("bmfac()");
310
311note("blsft()");
312
313note("brsft()");
314
315note("band()");
316
317note("bior()");
318
319note("bxor()");
320
321note("bnot()");
322
323note("bround()");
324
325# Add tests for rounding a non-integer to an integer. Fixme!
326
327$x = $zero -> copy() -> bround();
328cmp_ok($x, "==", 0, "bround(0)");
329is(ref($x), "Math::BigInt", "bround(0) => Math::BigInt");
330
331$x = $four -> copy() -> bround();
332cmp_ok($x, "==", 4, "bround(4)");
333is(ref($x), "Math::BigInt", "bround(4) => Math::BigInt");
334
335$x = $inf -> copy() -> bround();
336cmp_ok($x, "==", "inf", "bround(Inf)");
337is(ref($x), "Math::BigInt", "bround(Inf) => Math::BigInt");
338
339$x = $nan -> copy() -> bround();
340is($x, "NaN", "bround(NaN)");
341is(ref($x), "Math::BigInt", "bround(NaN) => Math::BigInt");
342
343note("bfround()");
344
345# Add tests for rounding a non-integer to an integer. Fixme!
346
347$x = $zero -> copy() -> bfround();
348cmp_ok($x, "==", 0, "bfround(0)");
349is(ref($x), "Math::BigInt", "bfround(0) => Math::BigInt");
350
351$x = $four -> copy() -> bfround();
352cmp_ok($x, "==", 4, "bfround(4)");
353is(ref($x), "Math::BigInt", "bfround(4) => Math::BigInt");
354
355$x = $inf -> copy() -> bfround();
356cmp_ok($x, "==", "inf", "bfround(Inf)");
357is(ref($x), "Math::BigInt", "bfround(Inf) => Math::BigInt");
358
359$x = $nan -> copy() -> bfround();
360is($x, "NaN", "bfround(NaN)");
361is(ref($x), "Math::BigInt", "bfround(NaN) => Math::BigInt");
362
363note("bfloor()");
364
365$x = $half -> copy() -> bfloor();
366cmp_ok($x, "==", 0, "bfloor(0)");
367is(ref($x), "Math::BigInt", "bfloor(0) => Math::BigInt");
368
369$x = $inf -> copy() -> bfloor();
370cmp_ok($x, "==", "Inf", "bfloor(Inf)");
371is(ref($x), "Math::BigInt", "bfloor(Inf) => Math::BigInt");
372
373$x = $nan -> copy() -> bfloor();
374is($x, "NaN", "bfloor(NaN)");
375is(ref($x), "Math::BigInt", "bfloor(NaN) => Math::BigInt");
376
377note("bceil()");
378
379$x = $half -> copy() -> bceil();
380cmp_ok($x, "==", 1, "bceil(0)");
381is(ref($x), "Math::BigInt", "bceil(0) => Math::BigInt");
382
383$x = $inf -> copy() -> bceil();
384cmp_ok($x, "==", "Inf", "bceil(Inf)");
385is(ref($x), "Math::BigInt", "bceil(Inf) => Math::BigInt");
386
387$x = $nan -> copy() -> bceil();
388is($x, "NaN", "bceil(NaN)");
389is(ref($x), "Math::BigInt", "bceil(NaN) => Math::BigInt");
390
391note("bint()");
392
393$x = $half -> copy() -> bint();
394cmp_ok($x, "==", 0, "bint(0)");
395is(ref($x), "Math::BigInt", "bint(0) => Math::BigInt");
396
397$x = $inf -> copy() -> bint();
398cmp_ok($x, "==", "Inf", "bint(Inf)");
399is(ref($x), "Math::BigInt", "bint(Inf) => Math::BigInt");
400
401$x = $nan -> copy() -> bint();
402is($x, "NaN", "bint(NaN)");
403is(ref($x), "Math::BigInt", "bint(NaN) => Math::BigInt");
404
405note("bgcd()");
406
407note("blcm()");
408
409# mantissa() ?
410
411# exponent() ?
412
413# parts() ?
414
415# sparts()
416
417# nparts()
418
419# eparts()
420
421# dparts()
422
423# fparts()
424
425# numerator()
426
427# denominator()
428
429#require 'upgrade.inc'; # all tests here for sharing
430