File Coverage

blib/lib/Math/BigInt/FastCalc.pm
Criterion Covered Total %
statement 28 33 84.8
branch 4 14 28.5
condition 0 15 0.0
subroutine 8 8 100.0
pod n/a
total 40 70 57.1


line stmt bran cond sub pod time code
1             package Math::BigInt::FastCalc;
2              
3 10     10   952533 use 5.006001;
  10         123  
4 10     10   55 use strict;
  10         18  
  10         216  
5 10     10   45 use warnings;
  10         19  
  10         294  
6              
7 10     10   65 use Carp qw< carp croak >;
  10         26  
  10         669  
8              
9 10     10   6853 use Math::BigInt::Calc 1.999801;
  10         246680  
  10         54  
10              
11             BEGIN {
12 10     10   4708 our @ISA = qw< Math::BigInt::Calc >;
13             }
14              
15             our $VERSION = '0.5015';
16              
17             my $MAX_EXP_F; # the maximum possible base 10 exponent with "no integer"
18             my $MAX_EXP_I; # the maximum possible base 10 exponent with "use integer"
19             my $BASE_LEN; # the current base exponent in use
20             my $USE_INT; # whether "use integer" is used in the computations
21              
22             sub _base_len {
23 3     3   4663459 my $class = shift;
24              
25 3 50       18 if (@_) { # if called as setter ...
26 0         0 my ($base_len, $use_int) = @_;
27              
28 0 0 0     0 croak "The base length must be a positive integer"
      0        
29             unless defined($base_len) && $base_len == int($base_len)
30             && $base_len > 0;
31              
32 0 0 0     0 if ( $use_int && ($base_len > $MAX_EXP_I) ||
      0        
      0        
33             !$use_int && ($base_len > $MAX_EXP_F))
34             {
35 0 0       0 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 0         0 return $class -> SUPER::_base_len($base_len, $use_int);
42             }
43              
44 3         27 return $class -> SUPER::_base_len();
45             }
46              
47             BEGIN {
48              
49 10     10   117 my @params = Math::BigInt::FastCalc -> SUPER::_base_len();
50 10         936 $BASE_LEN = $params[0];
51 10         21 $MAX_EXP_F = $params[8];
52 10         15 $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 10         68 require Config;
64 10         1084 my $max_exp_i = int(8 * $Config::Config{uvsize} * log(2) / log(10));
65 10 50       69 $MAX_EXP_I = $max_exp_i if $max_exp_i < $MAX_EXP_I;
66 10 50       75 $MAX_EXP_F = $MAX_EXP_I if $MAX_EXP_I < $MAX_EXP_F;
67              
68 10 50       48 ($BASE_LEN, $USE_INT) = $MAX_EXP_I > $MAX_EXP_F ? ($MAX_EXP_I, 1)
69             : ($MAX_EXP_F, 0);
70              
71 10         45 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              
81             sub api_version () { 2; }
82              
83             require XSLoader;
84             XSLoader::load(__PACKAGE__, $VERSION, Math::BigInt::Calc->_base_len());
85              
86             ##############################################################################
87              
88             1;
89              
90             __END__