9 | 9 |
|
10 | 10 |
sub CLONE_SKIP { 1 } # prevent cloning
|
11 | 11 |
|
12 | |
##############################################################################
|
13 | |
# routine to test internal state
|
14 | |
|
|
12 |
### same as overloading in Math::BigInt::Lib
|
|
13 |
use overload
|
|
14 |
# overload key: with_assign
|
|
15 |
|
|
16 |
'+' => sub {
|
|
17 |
my $class = ref $_[0];
|
|
18 |
my $x = $class -> _copy($_[0]);
|
|
19 |
my $y = ref($_[1]) ? $_[1] : $class -> _new($_[1]);
|
|
20 |
return $class -> _add($x, $y);
|
|
21 |
},
|
|
22 |
|
|
23 |
'-' => sub {
|
|
24 |
my $class = ref $_[0];
|
|
25 |
my ($x, $y);
|
|
26 |
if ($_[2]) { # if swapped
|
|
27 |
$y = $_[0];
|
|
28 |
$x = ref($_[1]) ? $_[1] : $class -> _new($_[1]);
|
|
29 |
} else {
|
|
30 |
$x = $class -> _copy($_[0]);
|
|
31 |
$y = ref($_[1]) ? $_[1] : $class -> _new($_[1]);
|
|
32 |
}
|
|
33 |
return $class -> _sub($x, $y);
|
|
34 |
},
|
|
35 |
|
|
36 |
'*' => sub {
|
|
37 |
my $class = ref $_[0];
|
|
38 |
my $x = $class -> _copy($_[0]);
|
|
39 |
my $y = ref($_[1]) ? $_[1] : $class -> _new($_[1]);
|
|
40 |
return $class -> _mul($x, $y);
|
|
41 |
},
|
|
42 |
|
|
43 |
'/' => sub {
|
|
44 |
my $class = ref $_[0];
|
|
45 |
my ($x, $y);
|
|
46 |
if ($_[2]) { # if swapped
|
|
47 |
$y = $_[0];
|
|
48 |
$x = ref($_[1]) ? $_[1] : $class -> _new($_[1]);
|
|
49 |
} else {
|
|
50 |
$x = $class -> _copy($_[0]);
|
|
51 |
$y = ref($_[1]) ? $_[1] : $class -> _new($_[1]);
|
|
52 |
}
|
|
53 |
return $class -> _div($x, $y);
|
|
54 |
},
|
|
55 |
|
|
56 |
'%' => sub {
|
|
57 |
my $class = ref $_[0];
|
|
58 |
my ($x, $y);
|
|
59 |
if ($_[2]) { # if swapped
|
|
60 |
$y = $_[0];
|
|
61 |
$x = ref($_[1]) ? $_[1] : $class -> _new($_[1]);
|
|
62 |
} else {
|
|
63 |
$x = $class -> _copy($_[0]);
|
|
64 |
$y = ref($_[1]) ? $_[1] : $class -> _new($_[1]);
|
|
65 |
}
|
|
66 |
return $class -> _mod($x, $y);
|
|
67 |
},
|
|
68 |
|
|
69 |
'**' => sub {
|
|
70 |
my $class = ref $_[0];
|
|
71 |
my ($x, $y);
|
|
72 |
if ($_[2]) { # if swapped
|
|
73 |
$y = $_[0];
|
|
74 |
$x = ref($_[1]) ? $_[1] : $class -> _new($_[1]);
|
|
75 |
} else {
|
|
76 |
$x = $class -> _copy($_[0]);
|
|
77 |
$y = ref($_[1]) ? $_[1] : $class -> _new($_[1]);
|
|
78 |
}
|
|
79 |
return $class -> _pow($x, $y);
|
|
80 |
},
|
|
81 |
|
|
82 |
'<<' => sub {
|
|
83 |
my $class = ref $_[0];
|
|
84 |
my ($x, $y);
|
|
85 |
if ($_[2]) { # if swapped
|
|
86 |
$y = $class -> _num($_[0]);
|
|
87 |
$x = ref($_[1]) ? $_[1] : $class -> _new($_[1]);
|
|
88 |
} else {
|
|
89 |
$x = $_[0];
|
|
90 |
$y = ref($_[1]) ? $class -> _num($_[1]) : $_[1];
|
|
91 |
}
|
|
92 |
return $class -> _blsft($x, $y);
|
|
93 |
},
|
|
94 |
|
|
95 |
'>>' => sub {
|
|
96 |
my $class = ref $_[0];
|
|
97 |
my ($x, $y);
|
|
98 |
if ($_[2]) { # if swapped
|
|
99 |
$y = $_[0];
|
|
100 |
$x = ref($_[1]) ? $_[1] : $class -> _new($_[1]);
|
|
101 |
} else {
|
|
102 |
$x = $class -> _copy($_[0]);
|
|
103 |
$y = ref($_[1]) ? $_[1] : $class -> _new($_[1]);
|
|
104 |
}
|
|
105 |
return $class -> _brsft($x, $y);
|
|
106 |
},
|
|
107 |
|
|
108 |
# overload key: num_comparison
|
|
109 |
|
|
110 |
'<' => sub {
|
|
111 |
my $class = ref $_[0];
|
|
112 |
my ($x, $y);
|
|
113 |
if ($_[2]) { # if swapped
|
|
114 |
$y = $_[0];
|
|
115 |
$x = ref($_[1]) ? $_[1] : $class -> _new($_[1]);
|
|
116 |
} else {
|
|
117 |
$x = $class -> _copy($_[0]);
|
|
118 |
$y = ref($_[1]) ? $_[1] : $class -> _new($_[1]);
|
|
119 |
}
|
|
120 |
return $class -> _acmp($x, $y) < 0;
|
|
121 |
},
|
|
122 |
|
|
123 |
'<=' => sub {
|
|
124 |
my $class = ref $_[0];
|
|
125 |
my ($x, $y);
|
|
126 |
if ($_[2]) { # if swapped
|
|
127 |
$y = $_[0];
|
|
128 |
$x = ref($_[1]) ? $_[1] : $class -> _new($_[1]);
|
|
129 |
} else {
|
|
130 |
$x = $class -> _copy($_[0]);
|
|
131 |
$y = ref($_[1]) ? $_[1] : $class -> _new($_[1]);
|
|
132 |
}
|
|
133 |
return $class -> _acmp($x, $y) <= 0;
|
|
134 |
},
|
|
135 |
|
|
136 |
'>' => sub {
|
|
137 |
my $class = ref $_[0];
|
|
138 |
my ($x, $y);
|
|
139 |
if ($_[2]) { # if swapped
|
|
140 |
$y = $_[0];
|
|
141 |
$x = ref($_[1]) ? $_[1] : $class -> _new($_[1]);
|
|
142 |
} else {
|
|
143 |
$x = $class -> _copy($_[0]);
|
|
144 |
$y = ref($_[1]) ? $_[1] : $class -> _new($_[1]);
|
|
145 |
}
|
|
146 |
return $class -> _acmp($x, $y) > 0;
|
|
147 |
},
|
|
148 |
|
|
149 |
'>=' => sub {
|
|
150 |
my $class = ref $_[0];
|
|
151 |
my ($x, $y);
|
|
152 |
if ($_[2]) { # if swapped
|
|
153 |
$y = $_[0];
|
|
154 |
$x = ref($_[1]) ? $_[1] : $class -> _new($_[1]);
|
|
155 |
} else {
|
|
156 |
$x = $class -> _copy($_[0]);
|
|
157 |
$y = ref($_[1]) ? $_[1] : $class -> _new($_[1]);
|
|
158 |
}
|
|
159 |
return $class -> _acmp($x, $y) >= 0;
|
|
160 |
},
|
|
161 |
|
|
162 |
'==' => sub {
|
|
163 |
my $class = ref $_[0];
|
|
164 |
my $x = $class -> _copy($_[0]);
|
|
165 |
my $y = ref($_[1]) ? $_[1] : $class -> _new($_[1]);
|
|
166 |
return $class -> _acmp($x, $y) == 0;
|
|
167 |
},
|
|
168 |
|
|
169 |
'!=' => sub {
|
|
170 |
my $class = ref $_[0];
|
|
171 |
my $x = $class -> _copy($_[0]);
|
|
172 |
my $y = ref($_[1]) ? $_[1] : $class -> _new($_[1]);
|
|
173 |
return $class -> _acmp($x, $y) != 0;
|
|
174 |
},
|
|
175 |
|
|
176 |
# overload key: 3way_comparison
|
|
177 |
|
|
178 |
'<=>' => sub {
|
|
179 |
my $class = ref $_[0];
|
|
180 |
my ($x, $y);
|
|
181 |
if ($_[2]) { # if swapped
|
|
182 |
$y = $_[0];
|
|
183 |
$x = ref($_[1]) ? $_[1] : $class -> _new($_[1]);
|
|
184 |
} else {
|
|
185 |
$x = $class -> _copy($_[0]);
|
|
186 |
$y = ref($_[1]) ? $_[1] : $class -> _new($_[1]);
|
|
187 |
}
|
|
188 |
return $class -> _acmp($x, $y);
|
|
189 |
},
|
|
190 |
|
|
191 |
# overload key: binary
|
|
192 |
|
|
193 |
'&' => sub {
|
|
194 |
my $class = ref $_[0];
|
|
195 |
my ($x, $y);
|
|
196 |
if ($_[2]) { # if swapped
|
|
197 |
$y = $_[0];
|
|
198 |
$x = ref($_[1]) ? $_[1] : $class -> _new($_[1]);
|
|
199 |
} else {
|
|
200 |
$x = $class -> _copy($_[0]);
|
|
201 |
$y = ref($_[1]) ? $_[1] : $class -> _new($_[1]);
|
|
202 |
}
|
|
203 |
return $class -> _and($x, $y);
|
|
204 |
},
|
|
205 |
|
|
206 |
'|' => sub {
|
|
207 |
my $class = ref $_[0];
|
|
208 |
my ($x, $y);
|
|
209 |
if ($_[2]) { # if swapped
|
|
210 |
$y = $_[0];
|
|
211 |
$x = ref($_[1]) ? $_[1] : $class -> _new($_[1]);
|
|
212 |
} else {
|
|
213 |
$x = $class -> _copy($_[0]);
|
|
214 |
$y = ref($_[1]) ? $_[1] : $class -> _new($_[1]);
|
|
215 |
}
|
|
216 |
return $class -> _or($x, $y);
|
|
217 |
},
|
|
218 |
|
|
219 |
'^' => sub {
|
|
220 |
my $class = ref $_[0];
|
|
221 |
my ($x, $y);
|
|
222 |
if ($_[2]) { # if swapped
|
|
223 |
$y = $_[0];
|
|
224 |
$x = ref($_[1]) ? $_[1] : $class -> _new($_[1]);
|
|
225 |
} else {
|
|
226 |
$x = $class -> _copy($_[0]);
|
|
227 |
$y = ref($_[1]) ? $_[1] : $class -> _new($_[1]);
|
|
228 |
}
|
|
229 |
return $class -> _xor($x, $y);
|
|
230 |
},
|
|
231 |
|
|
232 |
# overload key: func
|
|
233 |
|
|
234 |
'abs' => sub { $_[0] },
|
|
235 |
|
|
236 |
'sqrt' => sub {
|
|
237 |
my $class = ref $_[0];
|
|
238 |
return $class -> _sqrt($class -> _copy($_[0]));
|
|
239 |
},
|
|
240 |
|
|
241 |
'int' => sub { $_[0] -> copy() -> bint(); },
|
|
242 |
|
|
243 |
# overload key: conversion
|
|
244 |
|
|
245 |
'bool' => sub { ref($_[0]) -> _is_zero($_[0]) ? '' : 1; },
|
|
246 |
|
|
247 |
'""' => sub { ref($_[0]) -> _str($_[0]); },
|
|
248 |
|
|
249 |
'0+' => sub { ref($_[0]) -> _num($_[0]); },
|
|
250 |
|
|
251 |
'=' => sub { ref($_[0]) -> _copy($_[0]); },
|
|
252 |
|
|
253 |
;
|
|
254 |
|
|
255 |
### same as import() in Math::BigInt::Lib
|
|
256 |
sub import { }
|
|
257 |
|
|
258 |
### same as _check() in Math::BigInt::Lib
|
15 | 259 |
sub _check {
|
16 | |
my ($c, $x) = @_;
|
17 | |
return 0 if ref $x eq 'Math::BigInt::LTM';
|
18 | |
return "$x is not a reference to Math::BigInt::LTM";
|
19 | |
}
|
20 | |
|
21 | |
##############################################################################
|
22 | |
# Return the nth digit, negative values count backward.
|
23 | |
|
|
260 |
# used by the test suite
|
|
261 |
my ($class, $x) = @_;
|
|
262 |
return "Input is undefined" unless defined $x;
|
|
263 |
return "$x is not a reference" unless ref($x);
|
|
264 |
return 0;
|
|
265 |
}
|
|
266 |
|
|
267 |
### same as _digit() in Math::BigInt::Lib
|
24 | 268 |
sub _digit {
|
25 | |
my ($c, $x, $n) = @_;
|
26 | |
substr(_str($c, $x), -($n+1), 1);
|
27 | |
}
|
28 | |
|
29 | |
##############################################################################
|
30 | |
# Return a Perl numerical scalar.
|
31 | |
|
|
269 |
my ($class, $x, $n) = @_;
|
|
270 |
substr($class ->_str($x), -($n+1), 1);
|
|
271 |
}
|
|
272 |
|
|
273 |
### same as _num() in Math::BigInt::Lib
|
32 | 274 |
sub _num {
|
33 | |
my ($c, $x) = @_;
|
34 | |
return 0 + _str($c, $x);
|
35 | |
}
|
36 | |
|
37 | |
##############################################################################
|
38 | |
# _fac() - n! (factorial)
|
39 | |
|
|
275 |
my ($class, $x) = @_;
|
|
276 |
0 + $class -> _str($x);
|
|
277 |
}
|
|
278 |
|
|
279 |
### same as _fac() in Math::BigInt::Lib
|
40 | 280 |
sub _fac {
|
41 | |
my ($c, $x) = @_;
|
42 | |
if (_is_zero($c, $x) || _is_one($c, $x)) {
|
43 | |
_set($c, $x, 1);
|
44 | |
}
|
45 | |
else {
|
46 | |
my $copy = _copy($c, $x);
|
47 | |
my $one = _new($c, 1);
|
48 | |
while(_acmp($c, $copy, $one) > 0) {
|
49 | |
$copy = _dec($c, $copy);
|
50 | |
$x = _mul($c, $x, $copy);
|
51 | |
}
|
52 | |
}
|
|
281 |
# factorial
|
|
282 |
my ($class, $x) = @_;
|
|
283 |
|
|
284 |
my $two = $class -> _two();
|
|
285 |
|
|
286 |
if ($class -> _acmp($x, $two) < 0) {
|
|
287 |
return $class -> _one();
|
|
288 |
}
|
|
289 |
|
|
290 |
my $i = $class -> _copy($x);
|
|
291 |
while ($class -> _acmp($i, $two) > 0) {
|
|
292 |
$i = $class -> _dec($i);
|
|
293 |
$x = $class -> _mul($x, $i);
|
|
294 |
}
|
|
295 |
|
53 | 296 |
return $x;
|
54 | 297 |
}
|
55 | 298 |
|
56 | |
##############################################################################
|
57 | |
# Return binomial coefficient (n over k).
|
58 | |
# based on _nok() in Math::BigInt::GMP
|
59 | |
|
|
299 |
### same as _nok() in Math::BigInt::Lib
|
60 | 300 |
sub _nok {
|
|
301 |
# Return binomial coefficient (n over k).
|
|
302 |
# Given refs to arrays, return ref to array.
|
61 | 303 |
# First input argument is modified.
|
62 | |
my ($c, $n, $k) = @_;
|
|
304 |
|
|
305 |
my ($class, $n, $k) = @_;
|
63 | 306 |
|
64 | 307 |
# If k > n/2, or, equivalently, 2*k > n, compute nok(n, k) as
|
65 | 308 |
# nok(n, n-k), to minimize the number if iterations in the loop.
|
66 | 309 |
|
67 | 310 |
{
|
68 | |
my $twok = _mul($c, _two($c), _copy($c, $k)); # 2 * k
|
69 | |
if (_acmp($c, $twok, $n) > 0) { # if 2*k > n
|
70 | |
$k = _sub($c, _copy($c, $n), $k); # k = n - k
|
|
311 |
my $twok = $class -> _mul($class -> _two(), $class -> _copy($k));
|
|
312 |
if ($class -> _acmp($twok, $n) > 0) {
|
|
313 |
$k = $class -> _sub($class -> _copy($n), $k);
|
71 | 314 |
}
|
72 | 315 |
}
|
73 | 316 |
|
|
77 | 320 |
# | | = --------- = --------------- = --------- = 5 * - * -
|
78 | 321 |
# \ 3 / (7-3)! 3! 1*2*3*4 * 1*2*3 1 * 2 * 3 2 3
|
79 | 322 |
|
80 | |
if (_is_zero($c, $k)) {
|
81 | |
$n = _one($c);
|
82 | |
return $n;
|
|
323 |
if ($class -> _is_zero($k)) {
|
|
324 |
return $class -> _one();
|
83 | 325 |
}
|
84 | 326 |
|
85 | 327 |
# Make a copy of the original n, since we'll be modifying n in-place.
|
86 | 328 |
|
87 | |
my $n_orig = _copy($c, $n);
|
|
329 |
my $n_orig = $class -> _copy($n);
|
88 | 330 |
|
89 | 331 |
# n = 5, f = 6, d = 2 (cf. example above)
|
90 | 332 |
|
91 | |
_sub($c, $n, $k);
|
92 | |
_inc($c, $n);
|
93 | |
|
94 | |
my $f = _copy($c, $n);
|
95 | |
_inc($c, $f);
|
96 | |
|
97 | |
my $d = _two($c);
|
|
333 |
$n = $class -> _sub($n, $k);
|
|
334 |
$n = $class -> _inc($n);
|
|
335 |
|
|
336 |
my $f = $class -> _copy($n);
|
|
337 |
$class -> _inc($f);
|
|
338 |
|
|
339 |
my $d = $class -> _two();
|
98 | 340 |
|
99 | 341 |
# while f <= n (the original n, that is) ...
|
100 | 342 |
|
101 | |
while (_acmp($c, $f, $n_orig) <= 0) {
|
|
343 |
while ($class -> _acmp($f, $n_orig) <= 0) {
|
102 | 344 |
|
103 | 345 |
# n = (n * f / d) == 5 * 6 / 2 (cf. example above)
|
104 | 346 |
|
105 | |
_mul($c, $n, $f);
|
106 | |
_div($c, $n, $d);
|
|
347 |
$n = $class -> _mul($n, $f);
|
|
348 |
$n = $class -> _div($n, $d);
|
107 | 349 |
|
108 | 350 |
# f = 7, d = 3 (cf. example above)
|
109 | 351 |
|
110 | |
_inc($c, $f);
|
111 | |
_inc($c, $d);
|
|
352 |
$f = $class -> _inc($f);
|
|
353 |
$d = $class -> _inc($d);
|
112 | 354 |
}
|
113 | 355 |
|
114 | 356 |
return $n;
|
115 | 357 |
}
|
116 | 358 |
|
117 | |
##############################################################################
|
118 | |
# based on _log_int() in Math::BigInt::GMP
|
119 | |
|
|
359 |
### same as _log_int() in Math::BigInt::Lib
|
120 | 360 |
sub _log_int {
|
121 | |
my ($c, $x, $base) = @_;
|
|
361 |
# calculate integer log of $x to base $base
|
|
362 |
# ref to array, ref to array - return ref to array
|
|
363 |
my ($class, $x, $base) = @_;
|
122 | 364 |
|
123 | 365 |
# X == 0 => NaN
|
124 | |
return if _is_zero($c, $x);
|
125 | |
|
126 | |
$base = _new($c, 2) unless defined $base;
|
127 | |
$base = _new($c, $base) unless ref $base;
|
|
366 |
return if $class -> _is_zero($x);
|
|
367 |
|
|
368 |
$base = $class -> _new(2) unless defined($base);
|
|
369 |
$base = $class -> _new($base) unless ref($base);
|
128 | 370 |
|
129 | 371 |
# BASE 0 or 1 => NaN
|
130 | |
return if _is_zero($c, $base) || _is_one($c, $base);
|
|
372 |
return if $class -> _is_zero($base) || $class -> _is_one($base);
|
131 | 373 |
|
132 | 374 |
# X == 1 => 0 (is exact)
|
133 | |
if (_is_one($c, $x)) {
|
134 | |
_set($c, $x, 0);
|
135 | |
return $x, 1;
|
136 | |
}
|
137 | |
|
138 | |
my $cmp = _acmp($c, $x, $base);
|
|
375 |
if ($class -> _is_one($x)) {
|
|
376 |
return $class -> _zero(), 1;
|
|
377 |
}
|
|
378 |
|
|
379 |
my $cmp = $class -> _acmp($x, $base);
|
139 | 380 |
|
140 | 381 |
# X == BASE => 1 (is exact)
|
141 | 382 |
if ($cmp == 0) {
|
142 | |
_set($c, $x, 1);
|
143 | |
return $x, 1;
|
|
383 |
return $class -> _one(), 1;
|
144 | 384 |
}
|
145 | 385 |
|
146 | 386 |
# 1 < X < BASE => 0 (is truncated)
|
147 | 387 |
if ($cmp < 0) {
|
148 | |
_set($c, $x, 0);
|
149 | |
return $x, 0;
|
150 | |
}
|
151 | |
|
152 | |
my $x_org = _copy($c, $x);
|
153 | |
|
154 | |
# Alternative 1:
|
155 | |
|
156 | |
# Compute a guess for the result based on:
|
157 | |
# $guess = int( length_in_base_10(X) / ( log(base) / log(10) ) )
|
158 | |
|
159 | |
my $len = _alen($c, $x);
|
160 | |
my $log = log(_num($c, $base)) / log(10);
|
161 | |
|
162 | |
_set($c, $x, int($len / $log) - 1);
|
163 | |
|
164 | |
my $trial = _pow($c, _copy($c, $base), $x);
|
165 | |
my $acmp = _acmp($c, $trial, $x_org);
|
166 | |
|
167 | |
# Exact result?
|
168 | |
|
169 | |
return $x, 1 if $acmp == 0;
|
|
388 |
return $class -> _zero(), 0;
|
|
389 |
}
|
|
390 |
|
|
391 |
my $y;
|
|
392 |
|
|
393 |
# log(x) / log(b) = log(xm * 10^xe) / log(bm * 10^be)
|
|
394 |
# = (log(xm) + xe*(log(10))) / (log(bm) + be*log(10))
|
|
395 |
|
|
396 |
{
|
|
397 |
my $x_str = $class -> _str($x);
|
|
398 |
my $b_str = $class -> _str($base);
|
|
399 |
my $xm = "." . $x_str;
|
|
400 |
my $bm = "." . $b_str;
|
|
401 |
my $xe = length($x_str);
|
|
402 |
my $be = length($b_str);
|
|
403 |
my $log10 = log(10);
|
|
404 |
my $guess = int((log($xm) + $xe * $log10) / (log($bm) + $be * $log10));
|
|
405 |
$y = $class -> _new($guess);
|
|
406 |
}
|
|
407 |
|
|
408 |
my $trial = $class -> _pow($class -> _copy($base), $y);
|
|
409 |
my $acmp = $class -> _acmp($trial, $x);
|
|
410 |
|
|
411 |
# Did we get the exact result?
|
|
412 |
|
|
413 |
return $y, 1 if $acmp == 0;
|
170 | 414 |
|
171 | 415 |
# Too small?
|
172 | 416 |
|
173 | 417 |
while ($acmp < 0) {
|
174 | |
_mul($c, $trial, $base);
|
175 | |
_inc($c, $x);
|
176 | |
$acmp = _acmp($c, $trial, $x_org);
|
|
418 |
$trial = $class -> _mul($trial, $base);
|
|
419 |
$y = $class -> _inc($y);
|
|
420 |
$acmp = $class -> _acmp($trial, $x);
|
177 | 421 |
}
|
178 | 422 |
|
179 | 423 |
# Too big?
|
180 | 424 |
|
181 | 425 |
while ($acmp > 0) {
|
182 | |
_div($c, $trial, $base);
|
183 | |
_dec($c, $x);
|
184 | |
$acmp = _acmp($c, $trial, $x_org);
|
185 | |
}
|
186 | |
|
187 | |
return $x, 1 if $acmp == 0; # result is exact
|
188 | |
return $x, 0; # result is too small
|
189 | |
}
|
|
426 |
$trial = $class -> _div($trial, $base);
|
|
427 |
$y = $class -> _dec($y);
|
|
428 |
$acmp = $class -> _acmp($trial, $x);
|
|
429 |
}
|
|
430 |
|
|
431 |
return $y, 1 if $acmp == 0; # result is exact
|
|
432 |
return $y, 0; # result is too small
|
|
433 |
}
|
|
434 |
|
190 | 435 |
1;
|
191 | 436 |
|
192 | 437 |
__END__
|