Commit | Line | Data |
58cde26e |
1 | #!/usr/bin/perl -w |
2 | |
3 | # test accuracy, precicion and fallback, round_mode |
4 | |
5 | use strict; |
6 | use Test; |
7 | |
8 | BEGIN |
9 | { |
10 | $| = 1; |
11 | # chdir 't' if -d 't'; |
12 | unshift @INC, '../lib'; # for running manually |
13 | plan tests => 103; |
14 | } |
15 | |
16 | use Math::BigInt; |
17 | use Math::BigFloat; |
18 | |
19 | my ($x,$y,$z,$u); |
20 | |
21 | ############################################################################### |
22 | # test defaults and set/get |
23 | |
24 | ok_undef ($Math::BigInt::accuracy); |
25 | ok_undef ($Math::BigInt::precision); |
26 | ok ($Math::BigInt::div_scale,40); |
27 | ok (Math::BigInt::round_mode(),'even'); |
28 | ok ($Math::BigInt::rnd_mode,'even'); |
29 | |
30 | ok_undef ($Math::BigFloat::accuracy); |
31 | ok_undef ($Math::BigFloat::precision); |
32 | ok ($Math::BigFloat::div_scale,40); |
33 | ok ($Math::BigFloat::rnd_mode,'even'); |
34 | |
35 | # accuracy |
36 | foreach (qw/5 42 -1 0/) |
37 | { |
38 | ok ($Math::BigFloat::accuracy = $_,$_); |
39 | ok ($Math::BigInt::accuracy = $_,$_); |
40 | } |
41 | ok_undef ($Math::BigFloat::accuracy = undef); |
42 | ok_undef ($Math::BigInt::accuracy = undef); |
43 | |
44 | # precision |
45 | foreach (qw/5 42 -1 0/) |
46 | { |
47 | ok ($Math::BigFloat::precision = $_,$_); |
48 | ok ($Math::BigInt::precision = $_,$_); |
49 | } |
50 | ok_undef ($Math::BigFloat::precision = undef); |
51 | ok_undef ($Math::BigInt::precision = undef); |
52 | |
53 | # fallback |
54 | foreach (qw/5 42 1/) |
55 | { |
56 | ok ($Math::BigFloat::div_scale = $_,$_); |
57 | ok ($Math::BigInt::div_scale = $_,$_); |
58 | } |
59 | # illegal values are possible for fallback due to no accessor |
60 | |
61 | # round_mode |
62 | foreach (qw/odd even zero trunc +inf -inf/) |
63 | { |
64 | ok ($Math::BigFloat::rnd_mode = $_,$_); |
65 | ok ($Math::BigInt::rnd_mode = $_,$_); |
66 | } |
67 | $Math::BigFloat::rnd_mode = 4; |
68 | ok ($Math::BigFloat::rnd_mode,4); |
69 | ok ($Math::BigInt::rnd_mode,'-inf'); # from above |
70 | |
71 | $Math::BigInt::accuracy = undef; |
72 | $Math::BigInt::precision = undef; |
73 | # local copies |
74 | $x = Math::BigFloat->new(123.456); |
75 | ok_undef ($x->accuracy()); |
76 | ok ($x->accuracy(5),5); |
77 | ok_undef ($x->accuracy(undef),undef); |
78 | ok_undef ($x->precision()); |
79 | ok ($x->precision(5),5); |
80 | ok_undef ($x->precision(undef),undef); |
81 | |
82 | # see if MBF changes MBIs values |
83 | ok ($Math::BigInt::accuracy = 42,42); |
84 | ok ($Math::BigFloat::accuracy = 64,64); |
85 | ok ($Math::BigInt::accuracy,42); # should be still 42 |
86 | ok ($Math::BigFloat::accuracy,64); # should be still 64 |
87 | |
88 | ############################################################################### |
89 | # see if creating a number under set A or P will round it |
90 | |
91 | $Math::BigInt::accuracy = 4; |
92 | $Math::BigInt::precision = 3; |
93 | |
94 | ok (Math::BigInt->new(123456),123500); # with A |
95 | $Math::BigInt::accuracy = undef; |
96 | ok (Math::BigInt->new(123456),123000); # with P |
97 | |
98 | $Math::BigFloat::accuracy = 4; |
99 | $Math::BigFloat::precision = -1; |
100 | $Math::BigInt::precision = undef; |
101 | |
102 | ok (Math::BigFloat->new(123.456),123.5); # with A |
103 | $Math::BigFloat::accuracy = undef; |
104 | ok (Math::BigFloat->new(123.456),123.5); # with P from MBF, not MBI! |
105 | |
106 | $Math::BigFloat::precision = undef; |
107 | |
108 | ############################################################################### |
109 | # see if setting accuracy/precision actually rounds the number |
110 | |
111 | $x = Math::BigFloat->new(123.456); $x->accuracy(4); ok ($x,123.5); |
112 | $x = Math::BigFloat->new(123.456); $x->precision(-2); ok ($x,123.46); |
113 | |
114 | $x = Math::BigInt->new(123456); $x->accuracy(4); ok ($x,123500); |
115 | $x = Math::BigInt->new(123456); $x->precision(2); ok ($x,123500); |
116 | |
117 | ############################################################################### |
118 | # test actual rounding via round() |
119 | |
120 | $x = Math::BigFloat->new(123.456); |
121 | ok ($x->copy()->round(5,2),123.46); |
122 | ok ($x->copy()->round(4,2),123.5); |
123 | ok ($x->copy()->round(undef,-2),123.46); |
124 | ok ($x->copy()->round(undef,2),100); |
125 | |
126 | $x = Math::BigFloat->new(123.45000); |
127 | ok ($x->copy()->round(undef,-1,'odd'),123.5); |
128 | |
129 | # see if rounding is 'sticky' |
130 | $x = Math::BigFloat->new(123.4567); |
131 | $y = $x->copy()->bround(); # no-op since nowhere A or P defined |
132 | |
133 | ok ($y,123.4567); |
134 | $y = $x->copy()->round(5,2); |
135 | ok ($y->accuracy(),5); |
136 | ok_undef ($y->precision()); # A has precedence, so P still unset |
137 | $y = $x->copy()->round(undef,2); |
138 | ok ($y->precision(),2); |
139 | ok_undef ($y->accuracy()); # P has precedence, so A still unset |
140 | |
141 | # does copy work? |
142 | $x = Math::BigFloat->new(123.456); $x->accuracy(4); $x->precision(2); |
143 | $z = $x->copy(); ok ($z->accuracy(),4); ok ($z->precision(),2); |
144 | |
145 | ############################################################################### |
146 | # test wether operations round properly afterwards |
147 | # These tests are not complete, since they do not excercise every "return" |
148 | # statement in the op's. But heh, it's better than nothing... |
149 | |
150 | $x = Math::BigFloat->new(123.456); |
151 | $y = Math::BigFloat->new(654.321); |
152 | $x->{_a} = 5; # $x->accuracy(5) would round $x straightaway |
153 | $y->{_a} = 4; # $y->accuracy(4) would round $x straightaway |
154 | |
155 | $z = $x + $y; ok ($z,777.8); |
156 | $z = $y - $x; ok ($z,530.9); |
157 | $z = $y * $x; ok ($z,80780); |
158 | $z = $x ** 2; ok ($z,15241); |
159 | $z = $x * $x; ok ($z,15241); |
574bacfe |
160 | # not: $z = -$x; ok ($z,-123.46); ok ($x,123.456); |
58cde26e |
161 | $z = $x->copy(); $z->{_a} = 2; $z = $z / 2; ok ($z,62); |
162 | $x = Math::BigFloat->new(123456); $x->{_a} = 4; |
163 | $z = $x->copy; $z++; ok ($z,123500); |
164 | |
165 | $x = Math::BigInt->new(123456); |
166 | $y = Math::BigInt->new(654321); |
167 | $x->{_a} = 5; # $x->accuracy(5) would round $x straightaway |
168 | $y->{_a} = 4; # $y->accuracy(4) would round $x straightaway |
169 | |
170 | $z = $x + $y; ok ($z,777800); |
171 | $z = $y - $x; ok ($z,530900); |
172 | $z = $y * $x; ok ($z,80780000000); |
173 | $z = $x ** 2; ok ($z,15241000000); |
174 | # not yet: $z = -$x; ok ($z,-123460); ok ($x,123456); |
175 | $z = $x->copy; $z++; ok ($z,123460); |
176 | $z = $x->copy(); $z->{_a} = 2; $z = $z / 2; ok ($z,62000); |
177 | |
178 | ############################################################################### |
179 | # test mixed arguments |
180 | |
181 | $x = Math::BigFloat->new(10); |
182 | $u = Math::BigFloat->new(2.5); |
183 | $y = Math::BigInt->new(2); |
184 | |
185 | $z = $x + $y; ok ($z,12); ok (ref($z),'Math::BigFloat'); |
186 | $z = $x / $y; ok ($z,5); ok (ref($z),'Math::BigFloat'); |
187 | $z = $u * $y; ok ($z,5); ok (ref($z),'Math::BigFloat'); |
188 | |
189 | $y = Math::BigInt->new(12345); |
190 | $z = $u->copy()->bmul($y,2,0,'odd'); ok ($z,31000); |
191 | $z = $u->copy()->bmul($y,3,0,'odd'); ok ($z,30900); |
192 | $z = $u->copy()->bmul($y,undef,0,'odd'); ok ($z,30863); |
193 | $z = $u->copy()->bmul($y,undef,1,'odd'); ok ($z,30860); |
194 | $z = $u->copy()->bmul($y,undef,-1,'odd'); ok ($z,30862.5); |
195 | |
196 | # breakage: |
197 | # $z = $y->copy()->bmul($u,2,0,'odd'); ok ($z,31000); |
198 | # $z = $y * $u; ok ($z,5); ok (ref($z),'Math::BigInt'); |
199 | # $z = $y + $x; ok ($z,12); ok (ref($z),'Math::BigInt'); |
200 | # $z = $y / $x; ok ($z,0); ok (ref($z),'Math::BigInt'); |
201 | |
202 | # all done |
203 | |
204 | ############################################################################### |
205 | # Perl 5.005 does not like ok ($x,undef) |
206 | |
207 | sub ok_undef |
208 | { |
209 | my $x = shift; |
210 | |
211 | ok (1,1) and return if !defined $x; |
212 | ok ($x,'undef'); |
213 | } |
214 | |