The warning no more comes from util.c, it comes from numeric.c.
[p5sagit/p5-mst-13.2.git] / t / lib / mbimbf.t
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);
160 # not yet: $z = -$x;            ok ($z,-123.46); ok ($x,123.456);
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