Commit | Line | Data |
58cde26e |
1 | #!/usr/bin/perl -w |
2 | |
ee15d750 |
3 | # test rounding, accuracy, precicion and fallback, round_mode and mixing |
4 | # of classes |
58cde26e |
5 | |
dccbb853 |
6 | # Make sure you always quote any bare floating-point values, lest 123.46 will |
7 | # be stringified to 123.4599999999 due to limited float prevision. |
8 | |
58cde26e |
9 | use strict; |
10 | use Test; |
11 | |
12 | BEGIN |
13 | { |
14 | $| = 1; |
15 | # chdir 't' if -d 't'; |
16 | unshift @INC, '../lib'; # for running manually |
dccbb853 |
17 | plan tests => 254; |
58cde26e |
18 | } |
19 | |
ee15d750 |
20 | # for finding out whether round finds correct class |
21 | package Foo; |
22 | |
23 | use Math::BigInt; |
24 | use vars qw/@ISA $precision $accuracy $div_scale $round_mode/; |
25 | @ISA = qw/Math::BigInt/; |
26 | |
27 | $precision = 6; |
28 | $accuracy = 8; |
29 | $div_scale = 5; |
30 | $round_mode = 'odd'; |
31 | |
32 | sub new |
33 | { |
34 | my $class = shift; |
35 | my $self = { _a => undef, _p => undef, value => 5 }; |
36 | bless $self, $class; |
37 | } |
38 | |
39 | sub bstr |
40 | { |
41 | my $self = shift; |
42 | |
43 | return "$self->{value}"; |
44 | } |
45 | |
46 | # these will be called with the rounding precision or accuracy, depending on |
47 | # class |
48 | sub bround |
49 | { |
50 | my ($self,$a,$r) = @_; |
51 | $self->{value} = 'a' x $a; |
52 | return $self; |
53 | } |
54 | |
55 | sub bnorm |
56 | { |
57 | my $self = shift; |
58 | return $self; |
59 | } |
60 | |
61 | sub bfround |
62 | { |
63 | my ($self,$p,$r) = @_; |
64 | $self->{value} = 'p' x $p; |
65 | return $self; |
66 | } |
67 | |
68 | package main; |
69 | |
58cde26e |
70 | use Math::BigInt; |
71 | use Math::BigFloat; |
72 | |
73 | my ($x,$y,$z,$u); |
74 | |
75 | ############################################################################### |
76 | # test defaults and set/get |
77 | |
78 | ok_undef ($Math::BigInt::accuracy); |
79 | ok_undef ($Math::BigInt::precision); |
dccbb853 |
80 | ok_undef (Math::BigInt::accuracy()); |
81 | ok_undef (Math::BigInt::precision()); |
ee15d750 |
82 | ok_undef (Math::BigInt->accuracy()); |
83 | ok_undef (Math::BigInt->precision()); |
58cde26e |
84 | ok ($Math::BigInt::div_scale,40); |
ee15d750 |
85 | ok (Math::BigInt::div_scale(),40); |
86 | ok ($Math::BigInt::round_mode,'even'); |
58cde26e |
87 | ok (Math::BigInt::round_mode(),'even'); |
dccbb853 |
88 | ok (Math::BigInt->round_mode(),'even'); |
58cde26e |
89 | |
90 | ok_undef ($Math::BigFloat::accuracy); |
91 | ok_undef ($Math::BigFloat::precision); |
dccbb853 |
92 | ok_undef (Math::BigFloat::accuracy()); |
93 | ok_undef (Math::BigFloat::accuracy()); |
94 | ok_undef (Math::BigFloat->precision()); |
ee15d750 |
95 | ok_undef (Math::BigFloat->precision()); |
58cde26e |
96 | ok ($Math::BigFloat::div_scale,40); |
ee15d750 |
97 | ok (Math::BigFloat::div_scale(),40); |
98 | ok ($Math::BigFloat::round_mode,'even'); |
99 | ok (Math::BigFloat::round_mode(),'even'); |
dccbb853 |
100 | ok (Math::BigFloat->round_mode(),'even'); |
101 | |
102 | $x = eval 'Math::BigInt->round_mode("huhmbi");'; |
103 | ok ($@ =~ /^Unknown round mode huhmbi at/); |
104 | |
105 | $x = eval 'Math::BigFloat->round_mode("huhmbf");'; |
106 | ok ($@ =~ /^Unknown round mode huhmbf at/); |
ee15d750 |
107 | |
108 | # accessors |
109 | foreach my $class (qw/Math::BigInt Math::BigFloat/) |
110 | { |
111 | ok_undef ($class->accuracy()); |
112 | ok_undef ($class->precision()); |
113 | ok ($class->round_mode(),'even'); |
114 | ok ($class->div_scale(),40); |
115 | |
116 | ok ($class->div_scale(20),20); |
117 | $class->div_scale(40); ok ($class->div_scale(),40); |
118 | |
119 | ok ($class->round_mode('odd'),'odd'); |
120 | $class->round_mode('even'); ok ($class->round_mode(),'even'); |
121 | |
122 | ok ($class->accuracy(2),2); |
123 | $class->accuracy(3); ok ($class->accuracy(),3); |
124 | ok_undef ($class->accuracy(undef)); |
125 | |
126 | ok ($class->precision(2),2); |
127 | ok ($class->precision(-2),-2); |
128 | $class->precision(3); ok ($class->precision(),3); |
129 | ok_undef ($class->precision(undef)); |
130 | } |
58cde26e |
131 | |
132 | # accuracy |
133 | foreach (qw/5 42 -1 0/) |
134 | { |
135 | ok ($Math::BigFloat::accuracy = $_,$_); |
136 | ok ($Math::BigInt::accuracy = $_,$_); |
137 | } |
138 | ok_undef ($Math::BigFloat::accuracy = undef); |
139 | ok_undef ($Math::BigInt::accuracy = undef); |
140 | |
141 | # precision |
142 | foreach (qw/5 42 -1 0/) |
143 | { |
144 | ok ($Math::BigFloat::precision = $_,$_); |
145 | ok ($Math::BigInt::precision = $_,$_); |
146 | } |
147 | ok_undef ($Math::BigFloat::precision = undef); |
148 | ok_undef ($Math::BigInt::precision = undef); |
149 | |
150 | # fallback |
151 | foreach (qw/5 42 1/) |
152 | { |
153 | ok ($Math::BigFloat::div_scale = $_,$_); |
154 | ok ($Math::BigInt::div_scale = $_,$_); |
155 | } |
156 | # illegal values are possible for fallback due to no accessor |
157 | |
158 | # round_mode |
159 | foreach (qw/odd even zero trunc +inf -inf/) |
160 | { |
ee15d750 |
161 | ok ($Math::BigFloat::round_mode = $_,$_); |
162 | ok ($Math::BigInt::round_mode = $_,$_); |
58cde26e |
163 | } |
ee15d750 |
164 | $Math::BigFloat::round_mode = 'zero'; |
165 | ok ($Math::BigFloat::round_mode,'zero'); |
166 | ok ($Math::BigInt::round_mode,'-inf'); # from above |
58cde26e |
167 | |
168 | $Math::BigInt::accuracy = undef; |
169 | $Math::BigInt::precision = undef; |
170 | # local copies |
dccbb853 |
171 | $x = Math::BigFloat->new('123.456'); |
58cde26e |
172 | ok_undef ($x->accuracy()); |
173 | ok ($x->accuracy(5),5); |
174 | ok_undef ($x->accuracy(undef),undef); |
175 | ok_undef ($x->precision()); |
176 | ok ($x->precision(5),5); |
177 | ok_undef ($x->precision(undef),undef); |
178 | |
179 | # see if MBF changes MBIs values |
180 | ok ($Math::BigInt::accuracy = 42,42); |
181 | ok ($Math::BigFloat::accuracy = 64,64); |
182 | ok ($Math::BigInt::accuracy,42); # should be still 42 |
183 | ok ($Math::BigFloat::accuracy,64); # should be still 64 |
184 | |
185 | ############################################################################### |
186 | # see if creating a number under set A or P will round it |
187 | |
188 | $Math::BigInt::accuracy = 4; |
189 | $Math::BigInt::precision = 3; |
190 | |
191 | ok (Math::BigInt->new(123456),123500); # with A |
192 | $Math::BigInt::accuracy = undef; |
193 | ok (Math::BigInt->new(123456),123000); # with P |
194 | |
195 | $Math::BigFloat::accuracy = 4; |
196 | $Math::BigFloat::precision = -1; |
197 | $Math::BigInt::precision = undef; |
198 | |
dccbb853 |
199 | ok (Math::BigFloat->new('123.456'),'123.5'); # with A |
58cde26e |
200 | $Math::BigFloat::accuracy = undef; |
dccbb853 |
201 | ok (Math::BigFloat->new('123.456'),'123.5'); # with P from MBF, not MBI! |
58cde26e |
202 | |
203 | $Math::BigFloat::precision = undef; |
204 | |
205 | ############################################################################### |
206 | # see if setting accuracy/precision actually rounds the number |
207 | |
dccbb853 |
208 | $x = Math::BigFloat->new('123.456'); $x->accuracy(4); ok ($x,'123.5'); |
209 | $x = Math::BigFloat->new('123.456'); $x->precision(-2); ok ($x,'123.46'); |
58cde26e |
210 | |
dccbb853 |
211 | $x = Math::BigInt->new('123456'); $x->accuracy(4); ok ($x,123500); |
212 | $x = Math::BigInt->new('123456'); $x->precision(2); ok ($x,123500); |
58cde26e |
213 | |
214 | ############################################################################### |
215 | # test actual rounding via round() |
216 | |
dccbb853 |
217 | $x = Math::BigFloat->new('123.456'); |
218 | ok ($x->copy()->round(5,2),'123.46'); |
219 | ok ($x->copy()->round(4,2),'123.5'); |
220 | ok ($x->copy()->round(undef,-2),'123.46'); |
58cde26e |
221 | ok ($x->copy()->round(undef,2),100); |
222 | |
dccbb853 |
223 | $x = Math::BigFloat->new('123.45000'); |
224 | ok ($x->copy()->round(undef,-1,'odd'),'123.5'); |
58cde26e |
225 | |
226 | # see if rounding is 'sticky' |
dccbb853 |
227 | $x = Math::BigFloat->new('123.4567'); |
58cde26e |
228 | $y = $x->copy()->bround(); # no-op since nowhere A or P defined |
229 | |
230 | ok ($y,123.4567); |
231 | $y = $x->copy()->round(5,2); |
232 | ok ($y->accuracy(),5); |
233 | ok_undef ($y->precision()); # A has precedence, so P still unset |
234 | $y = $x->copy()->round(undef,2); |
235 | ok ($y->precision(),2); |
236 | ok_undef ($y->accuracy()); # P has precedence, so A still unset |
237 | |
ee15d750 |
238 | # see if setting A clears P and vice versa |
dccbb853 |
239 | $x = Math::BigFloat->new('123.4567'); |
240 | ok ($x,'123.4567'); |
ee15d750 |
241 | ok ($x->accuracy(4),4); |
242 | ok ($x->precision(-2),-2); # clear A |
243 | ok_undef ($x->accuracy()); |
244 | |
dccbb853 |
245 | $x = Math::BigFloat->new('123.4567'); |
246 | ok ($x,'123.4567'); |
ee15d750 |
247 | ok ($x->precision(-2),-2); |
248 | ok ($x->accuracy(4),4); # clear P |
249 | ok_undef ($x->precision()); |
250 | |
58cde26e |
251 | # does copy work? |
252 | $x = Math::BigFloat->new(123.456); $x->accuracy(4); $x->precision(2); |
ee15d750 |
253 | $z = $x->copy(); ok_undef ($z->accuracy(),undef); ok ($z->precision(),2); |
58cde26e |
254 | |
255 | ############################################################################### |
256 | # test wether operations round properly afterwards |
257 | # These tests are not complete, since they do not excercise every "return" |
258 | # statement in the op's. But heh, it's better than nothing... |
259 | |
dccbb853 |
260 | $x = Math::BigFloat->new('123.456'); |
261 | $y = Math::BigFloat->new('654.321'); |
58cde26e |
262 | $x->{_a} = 5; # $x->accuracy(5) would round $x straightaway |
263 | $y->{_a} = 4; # $y->accuracy(4) would round $x straightaway |
264 | |
dccbb853 |
265 | $z = $x + $y; ok ($z,'777.8'); |
266 | $z = $y - $x; ok ($z,'530.9'); |
267 | $z = $y * $x; ok ($z,'80780'); |
268 | $z = $x ** 2; ok ($z,'15241'); |
269 | $z = $x * $x; ok ($z,'15241'); |
ee15d750 |
270 | |
dccbb853 |
271 | # not: $z = -$x; ok ($z,'-123.46'); ok ($x,'123.456'); |
58cde26e |
272 | $z = $x->copy(); $z->{_a} = 2; $z = $z / 2; ok ($z,62); |
273 | $x = Math::BigFloat->new(123456); $x->{_a} = 4; |
274 | $z = $x->copy; $z++; ok ($z,123500); |
275 | |
276 | $x = Math::BigInt->new(123456); |
277 | $y = Math::BigInt->new(654321); |
278 | $x->{_a} = 5; # $x->accuracy(5) would round $x straightaway |
279 | $y->{_a} = 4; # $y->accuracy(4) would round $x straightaway |
280 | |
281 | $z = $x + $y; ok ($z,777800); |
282 | $z = $y - $x; ok ($z,530900); |
283 | $z = $y * $x; ok ($z,80780000000); |
284 | $z = $x ** 2; ok ($z,15241000000); |
285 | # not yet: $z = -$x; ok ($z,-123460); ok ($x,123456); |
286 | $z = $x->copy; $z++; ok ($z,123460); |
287 | $z = $x->copy(); $z->{_a} = 2; $z = $z / 2; ok ($z,62000); |
288 | |
ee15d750 |
289 | $x = Math::BigInt->new(123400); $x->{_a} = 4; |
290 | ok ($x->bnot(),-123400); # not -1234001 |
291 | |
292 | # both babs() and bneg() don't need to round, since the input will already |
293 | # be rounded (either as $x or via new($string)), and they don't change the |
294 | # value |
295 | # The two tests below peek at this by using _a illegally |
296 | $x = Math::BigInt->new(-123401); $x->{_a} = 4; |
297 | ok ($x->babs(),123401); |
298 | $x = Math::BigInt->new(-123401); $x->{_a} = 4; |
299 | ok ($x->bneg(),123401); |
300 | |
58cde26e |
301 | ############################################################################### |
302 | # test mixed arguments |
303 | |
304 | $x = Math::BigFloat->new(10); |
305 | $u = Math::BigFloat->new(2.5); |
306 | $y = Math::BigInt->new(2); |
307 | |
308 | $z = $x + $y; ok ($z,12); ok (ref($z),'Math::BigFloat'); |
309 | $z = $x / $y; ok ($z,5); ok (ref($z),'Math::BigFloat'); |
310 | $z = $u * $y; ok ($z,5); ok (ref($z),'Math::BigFloat'); |
311 | |
312 | $y = Math::BigInt->new(12345); |
313 | $z = $u->copy()->bmul($y,2,0,'odd'); ok ($z,31000); |
314 | $z = $u->copy()->bmul($y,3,0,'odd'); ok ($z,30900); |
315 | $z = $u->copy()->bmul($y,undef,0,'odd'); ok ($z,30863); |
316 | $z = $u->copy()->bmul($y,undef,1,'odd'); ok ($z,30860); |
317 | $z = $u->copy()->bmul($y,undef,-1,'odd'); ok ($z,30862.5); |
318 | |
319 | # breakage: |
320 | # $z = $y->copy()->bmul($u,2,0,'odd'); ok ($z,31000); |
321 | # $z = $y * $u; ok ($z,5); ok (ref($z),'Math::BigInt'); |
322 | # $z = $y + $x; ok ($z,12); ok (ref($z),'Math::BigInt'); |
323 | # $z = $y / $x; ok ($z,0); ok (ref($z),'Math::BigInt'); |
324 | |
ee15d750 |
325 | ############################################################################### |
326 | # rounding in bdiv with fallback and already set A or P |
327 | |
328 | $Math::BigFloat::accuracy = undef; |
329 | $Math::BigFloat::precision = undef; |
330 | $Math::BigFloat::div_scale = 40; |
331 | |
332 | $x = Math::BigFloat->new(10); $x->{_a} = 4; |
333 | ok ($x->bdiv(3),'3.333'); |
334 | ok ($x->{_a},4); # set's it since no fallback |
335 | |
336 | $x = Math::BigFloat->new(10); $x->{_a} = 4; $y = Math::BigFloat->new(3); |
337 | ok ($x->bdiv($y),'3.333'); |
338 | ok ($x->{_a},4); # set's it since no fallback |
339 | |
340 | # rounding to P of x |
341 | $x = Math::BigFloat->new(10); $x->{_p} = -2; |
342 | ok ($x->bdiv(3),'3.33'); |
343 | |
344 | # round in div with requested P |
345 | $x = Math::BigFloat->new(10); |
346 | ok ($x->bdiv(3,undef,-2),'3.33'); |
347 | |
348 | # round in div with requested P greater than fallback |
349 | $Math::BigFloat::div_scale = 5; |
350 | $x = Math::BigFloat->new(10); |
351 | ok ($x->bdiv(3,undef,-8),'3.33333333'); |
352 | $Math::BigFloat::div_scale = 40; |
353 | |
354 | $x = Math::BigFloat->new(10); $y = Math::BigFloat->new(3); $y->{_a} = 4; |
355 | ok ($x->bdiv($y),'3.333'); |
356 | ok ($x->{_a},4); ok ($y->{_a},4); # set's it since no fallback |
357 | ok_undef ($x->{_p}); ok_undef ($y->{_p}); |
358 | |
359 | # rounding to P of y |
360 | $x = Math::BigFloat->new(10); $y = Math::BigFloat->new(3); $y->{_p} = -2; |
361 | ok ($x->bdiv($y),'3.33'); |
362 | ok ($x->{_p},-2); |
363 | ok ($y->{_p},-2); |
364 | ok_undef ($x->{_a}); ok_undef ($y->{_a}); |
365 | |
366 | ############################################################################### |
367 | # test whether bround(-n) fails in MBF (undocumented in MBI) |
368 | eval { $x = Math::BigFloat->new(1); $x->bround(-2); }; |
369 | ok ($@ =~ /^bround\(\) needs positive accuracy/,1); |
370 | |
371 | # test whether rounding to higher accuracy is no-op |
372 | $x = Math::BigFloat->new(1); $x->{_a} = 4; |
373 | ok ($x,'1.000'); |
374 | $x->bround(6); # must be no-op |
375 | ok ($x->{_a},4); |
376 | ok ($x,'1.000'); |
377 | |
378 | $x = Math::BigInt->new(1230); $x->{_a} = 3; |
379 | ok ($x,'1230'); |
380 | $x->bround(6); # must be no-op |
381 | ok ($x->{_a},3); |
382 | ok ($x,'1230'); |
383 | |
384 | # bround(n) should set _a |
385 | $x->bround(2); # smaller works |
386 | ok ($x,'1200'); |
387 | ok ($x->{_a},2); |
388 | |
389 | # bround(-n) is undocumented and only used by MBF |
390 | # bround(-n) should set _a |
391 | $x = Math::BigInt->new(12345); |
392 | $x->bround(-1); |
393 | ok ($x,'12300'); |
394 | ok ($x->{_a},4); |
395 | |
396 | # bround(-n) should set _a |
397 | $x = Math::BigInt->new(12345); |
398 | $x->bround(-2); |
399 | ok ($x,'12000'); |
400 | ok ($x->{_a},3); |
401 | |
402 | # bround(-n) should set _a |
403 | $x = Math::BigInt->new(12345); $x->{_a} = 5; |
404 | $x->bround(-3); |
405 | ok ($x,'10000'); |
406 | ok ($x->{_a},2); |
407 | |
408 | # bround(-n) should set _a |
409 | $x = Math::BigInt->new(12345); $x->{_a} = 5; |
410 | $x->bround(-4); |
411 | ok ($x,'00000'); |
412 | ok ($x->{_a},1); |
413 | |
414 | # bround(-n) should be noop if n too big |
415 | $x = Math::BigInt->new(12345); |
416 | $x->bround(-5); |
417 | ok ($x,'0'); # scale to "big" => 0 |
418 | ok ($x->{_a},0); |
419 | |
420 | # bround(-n) should be noop if n too big |
421 | $x = Math::BigInt->new(54321); |
422 | $x->bround(-5); |
423 | ok ($x,'100000'); # used by MBF to round 0.0054321 at 0.0_6_00000 |
424 | ok ($x->{_a},0); |
425 | |
426 | # bround(-n) should be noop if n too big |
427 | $x = Math::BigInt->new(54321); $x->{_a} = 5; |
428 | $x->bround(-6); |
429 | ok ($x,'100000'); # no-op |
430 | ok ($x->{_a},0); |
431 | |
432 | # bround(n) should set _a |
433 | $x = Math::BigInt->new(12345); $x->{_a} = 5; |
434 | $x->bround(5); # must be no-op |
435 | ok ($x,'12345'); |
436 | ok ($x->{_a},5); |
437 | |
438 | # bround(n) should set _a |
439 | $x = Math::BigInt->new(12345); $x->{_a} = 5; |
440 | $x->bround(6); # must be no-op |
441 | ok ($x,'12345'); |
442 | |
443 | $x = Math::BigFloat->new(0.0061); $x->bfround(-2); |
444 | ok ($x,0.01); |
445 | |
446 | ############################################################################### |
447 | # rounding with already set precision/accuracy |
448 | |
449 | $x = Math::BigFloat->new(1); $x->{_p} = -5; |
450 | ok ($x,'1.00000'); |
451 | |
452 | # further rounding donw |
453 | ok ($x->bfround(-2),'1.00'); |
454 | ok ($x->{_p},-2); |
455 | |
456 | $x = Math::BigFloat->new(12345); $x->{_a} = 5; |
457 | ok ($x->bround(2),'12000'); |
458 | ok ($x->{_a},2); |
459 | |
dccbb853 |
460 | $x = Math::BigFloat->new('1.2345'); $x->{_a} = 5; |
ee15d750 |
461 | ok ($x->bround(2),'1.2'); |
462 | ok ($x->{_a},2); |
463 | |
464 | # mantissa/exponent format and A/P |
dccbb853 |
465 | $x = Math::BigFloat->new('12345.678'); $x->accuracy(4); |
ee15d750 |
466 | ok ($x,'12350'); ok ($x->{_a},4); ok_undef ($x->{_p}); |
467 | ok ($x->{_m}->{_f},1); ok ($x->{_e}->{_f},1); |
468 | ok_undef ($x->{_m}->{_a}); ok_undef ($x->{_e}->{_a}); |
469 | ok_undef ($x->{_m}->{_p}); ok_undef ($x->{_e}->{_p}); |
470 | |
471 | # check for no A/P in case of fallback |
472 | # result |
473 | $x = Math::BigFloat->new(100) / 3; |
474 | ok_undef ($x->{_a}); ok_undef ($x->{_p}); |
475 | |
476 | # result & reminder |
477 | $x = Math::BigFloat->new(100) / 3; ($x,$y) = $x->bdiv(3); |
478 | ok_undef ($x->{_a}); ok_undef ($x->{_p}); |
479 | ok_undef ($y->{_a}); ok_undef ($y->{_p}); |
480 | |
481 | ############################################################################### |
482 | # math with two numbers with differen A and P |
483 | |
484 | $x = Math::BigFloat->new(12345); $x->accuracy(4); # '12340' |
485 | $y = Math::BigFloat->new(12345); $y->accuracy(2); # '12000' |
486 | ok ($x+$y,24000); # 12340+12000=> 24340 => 24000 |
487 | |
488 | $x = Math::BigFloat->new(54321); $x->accuracy(4); # '12340' |
489 | $y = Math::BigFloat->new(12345); $y->accuracy(3); # '12000' |
490 | ok ($x-$y,42000); # 54320+12300=> 42020 => 42000 |
491 | |
dccbb853 |
492 | $x = Math::BigFloat->new('1.2345'); $x->precision(-2); # '1.23' |
493 | $y = Math::BigFloat->new('1.2345'); $y->precision(-4); # '1.2345' |
494 | ok ($x+$y,'2.46'); # 1.2345+1.2300=> 2.4645 => 2.46 |
ee15d750 |
495 | |
496 | ############################################################################### |
497 | # round should find and use proper class |
498 | |
499 | $x = Foo->new(); |
500 | ok ($x->round($Foo::accuracy),'a' x $Foo::accuracy); |
501 | ok ($x->round(undef,$Foo::precision),'p' x $Foo::precision); |
502 | ok ($x->bfround($Foo::precision),'p' x $Foo::precision); |
503 | ok ($x->bround($Foo::accuracy),'a' x $Foo::accuracy); |
504 | |
505 | ############################################################################### |
506 | # find out whether _find_round_parameters is doing what's it's supposed to do |
507 | |
508 | $Math::BigInt::accuracy = undef; |
509 | $Math::BigInt::precision = undef; |
510 | $Math::BigInt::div_scale = 40; |
511 | $Math::BigInt::round_mode = 'odd'; |
512 | |
513 | $x = Math::BigInt->new(123); |
514 | my @params = $x->_find_round_parameters(); |
515 | ok (scalar @params,1); # nothing to round |
516 | |
517 | @params = $x->_find_round_parameters(1); |
518 | ok (scalar @params,4); # a=1 |
519 | ok ($params[0],$x); # self |
520 | ok ($params[1],1); # a |
521 | ok_undef ($params[2]); # p |
522 | ok ($params[3],'odd'); # round_mode |
523 | |
524 | @params = $x->_find_round_parameters(undef,2); |
525 | ok (scalar @params,4); # p=2 |
526 | ok ($params[0],$x); # self |
527 | ok_undef ($params[1]); # a |
528 | ok ($params[2],2); # p |
529 | ok ($params[3],'odd'); # round_mode |
530 | |
531 | eval { @params = $x->_find_round_parameters(undef,2,'foo'); }; |
532 | ok ($@ =~ /^Unknown round mode 'foo'/,1); |
533 | |
534 | @params = $x->_find_round_parameters(undef,2,'+inf'); |
535 | ok (scalar @params,4); # p=2 |
536 | ok ($params[0],$x); # self |
537 | ok_undef ($params[1]); # a |
538 | ok ($params[2],2); # p |
539 | ok ($params[3],'+inf'); # round_mode |
540 | |
541 | @params = $x->_find_round_parameters(2,-2,'+inf'); |
542 | ok (scalar @params,4); # p=2 |
543 | ok ($params[0],$x); # self |
544 | ok ($params[1],2); # a |
545 | ok ($params[2],-2); # p |
546 | ok ($params[3],'+inf'); # round_mode |
547 | |
58cde26e |
548 | # all done |
549 | |
550 | ############################################################################### |
551 | # Perl 5.005 does not like ok ($x,undef) |
552 | |
553 | sub ok_undef |
554 | { |
555 | my $x = shift; |
556 | |
557 | ok (1,1) and return if !defined $x; |
558 | ok ($x,'undef'); |
559 | } |
560 | |