1package Math::BigInt::FastCalc;
2
3use 5.006001;
4use strict;
5use warnings;
6
7use Carp qw< carp croak >;
8
9use Math::BigInt::Calc 1.999801;
10
11BEGIN {
12    our @ISA = qw< Math::BigInt::Calc >;
13}
14
15our $VERSION = '0.5012';
16
17my $MAX_EXP_F;      # the maximum possible base 10 exponent with "no integer"
18my $MAX_EXP_I;      # the maximum possible base 10 exponent with "use integer"
19my $BASE_LEN;       # the current base exponent in use
20my $USE_INT;        # whether "use integer" is used in the computations
21
22sub _base_len {
23    my $class = shift;
24
25    if (@_) {                           # if called as setter ...
26        my ($base_len, $use_int) = @_;
27
28        croak "The base length must be a positive integer"
29          unless defined($base_len) && $base_len == int($base_len)
30                 && $base_len > 0;
31
32        if ( $use_int && ($base_len > $MAX_EXP_I) ||
33            !$use_int && ($base_len > $MAX_EXP_F))
34        {
35            croak "The maximum base length (exponent) is $MAX_EXP_I with",
36              " 'use integer' and $MAX_EXP_F without 'use integer'. The",
37              " requested settings, a base length of $base_len ",
38              $use_int ? "with" : "without", " 'use integer', is invalid.";
39        }
40
41        return $class -> SUPER::_base_len($base_len, $use_int);
42    }
43
44    return $class -> SUPER::_base_len();
45}
46
47BEGIN {
48
49    my @params = Math::BigInt::FastCalc -> SUPER::_base_len();
50    $BASE_LEN  = $params[0];
51    $MAX_EXP_F = $params[8];
52    $MAX_EXP_I = $params[9];
53
54    # With quadmath support it should work with a base length of 17, because the
55    # maximum intermediate value used in the computations is less than 2**113.
56    # However, for some reason a base length of 17 doesn't work, but trial and
57    # error shows that a base length of 15 works for all methods except
58    # _is_odd() and _is_even(). These two methods determine whether the least
59    # significand component is odd or even by converting it to a UV and do a
60    # bitwise & operation. Because of this, we need to limit the base length to
61    # what fits inside an UV.
62
63    require Config;
64    my $max_exp_i = int(8 * $Config::Config{uvsize} * log(2) / log(10));
65    $MAX_EXP_I = $max_exp_i if $max_exp_i < $MAX_EXP_I;
66    $MAX_EXP_F = $MAX_EXP_I if $MAX_EXP_I < $MAX_EXP_F;
67
68    ($BASE_LEN, $USE_INT) = $MAX_EXP_I > $MAX_EXP_F ? ($MAX_EXP_I, 1)
69                                                    : ($MAX_EXP_F, 0);
70
71    Math::BigInt::FastCalc -> SUPER::_base_len($BASE_LEN, $USE_INT);
72}
73
74##############################################################################
75# global constants, flags and accessory
76
77# Announce that we are compatible with MBI v1.83 and up. This method has been
78# made redundant. Each backend is now a subclass of Math::BigInt::Lib, which
79# provides the methods not present in the subclasses.
80
81sub api_version () { 2; }
82
83require XSLoader;
84XSLoader::load(__PACKAGE__, $VERSION, Math::BigInt::Calc->_base_len());
85
86##############################################################################
87
881;
89
90__END__
91
92=pod
93
94=head1 NAME
95
96Math::BigInt::FastCalc - Math::BigInt::Calc with some XS for more speed
97
98=head1 SYNOPSIS
99
100    # to use it with Math::BigInt
101    use Math::BigInt lib => 'FastCalc';
102
103    # to use it with Math::BigFloat
104    use Math::BigFloat lib => 'FastCalc';
105
106    # to use it with Math::BigRat
107    use Math::BigRat lib => 'FastCalc';
108
109=head1 DESCRIPTION
110
111Math::BigInt::FastCalc inherits from Math::BigInt::Calc.
112
113Provides support for big integer calculations. Not intended to be used by
114other modules. Other modules which sport the same functions can also be used
115to support Math::BigInt, like L<Math::BigInt::GMP> or L<Math::BigInt::Pari>.
116
117In order to allow for multiple big integer libraries, Math::BigInt was
118rewritten to use library modules for core math routines. Any module which
119follows the same API as this can be used instead by using the following:
120
121    use Math::BigInt lib => 'libname';
122
123'libname' is either the long name ('Math::BigInt::Pari'), or only the short
124version like 'Pari'. To use this library:
125
126    use Math::BigInt lib => 'FastCalc';
127
128The default behaviour is to chose the best internal representation of big
129integers, but the base length used in the internal representation can be
130specified explicitly. Note that this must be done before Math::BigInt is loaded.
131For example,
132
133    use Math::BigInt::FastCalc base_len => 3;
134    use Math::BigInt lib => 'FastCalc';
135
136=head1 STORAGE
137
138Math::BigInt::FastCalc works exactly like Math::BigInt::Calc. Numbers are
139stored in decimal form chopped into parts.
140
141=head1 METHODS
142
143The following functions are now implemented in FastCalc.xs:
144
145    _is_odd         _is_even        _is_one         _is_zero
146    _is_two         _is_ten
147    _zero           _one            _two            _ten
148    _acmp           _len
149    _inc            _dec
150    __strip_zeros   _copy
151
152=head1 BUGS
153
154Please report any bugs or feature requests to
155C<bug-math-bigint-fastcalc at rt.cpan.org>, or through the web interface at
156L<https://rt.cpan.org/Ticket/Create.html?Queue=Math-BigInt-FastCalc>
157(requires login). We will be notified, and then you'll automatically be
158notified of progress on your bug as I make changes.
159
160=head1 SUPPORT
161
162After installing, you can find documentation for this module with the perldoc
163command.
164
165    perldoc Math::BigInt::FastCalc
166
167You can also look for information at:
168
169=over 4
170
171=item GitHub
172
173L<https://github.com/pjacklam/p5-Math-BigInt-FastCalc>
174
175=item RT: CPAN's request tracker
176
177L<https://rt.cpan.org/Dist/Display.html?Name=Math-BigInt-FastCalc>
178
179=item MetaCPAN
180
181L<https://metacpan.org/release/Math-BigInt-FastCalc>
182
183=item CPAN Testers Matrix
184
185L<http://matrix.cpantesters.org/?dist=Math-BigInt-FastCalc>
186
187=item CPAN Ratings
188
189L<https://cpanratings.perl.org/dist/Math-BigInt-FastCalc>
190
191=back
192
193=head1 LICENSE
194
195This program is free software; you may redistribute it and/or modify it under
196the same terms as Perl itself.
197
198=head1 AUTHORS
199
200Original math code by Mark Biggar, rewritten by Tels L<http://bloodgate.com/>
201in late 2000.
202
203Separated from Math::BigInt and shaped API with the help of John Peacock.
204
205Fixed, sped-up and enhanced by Tels http://bloodgate.com 2001-2003.
206Further streamlining (api_version 1 etc.) by Tels 2004-2007.
207
208Maintained by Peter John Acklam E<lt>pjacklam@gmail.comE<gt> 2010-2021.
209
210=head1 SEE ALSO
211
212L<Math::BigInt::Lib> for a description of the API.
213
214Alternative libraries L<Math::BigInt::Calc>, L<Math::BigInt::GMP>, and
215L<Math::BigInt::Pari>.
216
217Some of the modules that use these libraries L<Math::BigInt>,
218L<Math::BigFloat>, and L<Math::BigRat>.
219
220=cut
221