File Coverage

lib/Machine/Epsilon.pm
Criterion Covered Total %
statement 22 27 81.4
branch 5 8 62.5
condition n/a
subroutine 4 4 100.0
pod 1 1 100.0
total 32 40 80.0


line stmt bran cond sub pod time code
1             package Machine::Epsilon;
2 1     1   582 use strict;
  1         1  
  1         27  
3 1     1   3 use warnings;
  1         1  
  1         26  
4              
5 1     1   2 use Exporter;
  1         1  
  1         202  
6             our @ISA = qw(Exporter);
7             our @EXPORT = qw(machine_epsilon); ## no critic (ProhibitAutomaticExportation)
8              
9             our $VERSION = '1.0.2';
10              
11             =head1 NAME
12              
13             Machine::Epsilon - The maximum relative error while rounding a floating point number
14              
15             =head1 SYNOPSIS
16              
17              
18             use Machine::Epsilon; # imports machine_epsilon() automatically
19              
20             my $epsilon = machine_epsilon();
21              
22             =cut
23              
24             =head1 FUNCTIONS
25              
26             =head2 machine_epsilon
27              
28             Returns the rounding error for the machine.
29              
30             =cut
31              
32             my $epsilon;
33              
34             sub machine_epsilon {
35              
36 1 50   1 1 599 return $epsilon if $epsilon;
37              
38             # Machine accuracy for 32-bit floating point number
39 1         1 my $ma_32bit_23mantissa = 1.0 / (2**23);
40              
41             # Machine accuracy for 64-bit floating point number
42 1         2 my $ma_64bit_52mantissa = 1.0 / (2**52);
43              
44             # Machine accuracy for 128-bit floating point number (e.g. IBM AIX)
45 1         2 my $ma_128bit_105mantissa = 1.0 / (2**112);
46              
47             # Always start with a power of 2 to avoid roundoff errors!!
48 1         1 my $e = 1.0;
49 1         1 while (1) {
50 53 100       60 if (1.0 + $e / 2 == 1.0) { last; }
  1         1  
51 52         27 $e = $e / 2.0;
52              
53             # Accuracy already better than a 128-bit machine!!
54 52 50       55 if ($e < $ma_128bit_105mantissa) {
55 0         0 warn "Machine accuracy seems too good to be true!! "
56             . "Do we have such a powerful machine? Assuming that "
57             . "something isn't right, and returning machine accuracy "
58             . "for 64 bit double.";
59 0         0 $e = $ma_64bit_52mantissa;
60 0         0 last;
61             }
62             }
63              
64             # If accuracy is very bad, we return the minimum accuracy for a 32-bit double
65 1 50       3 if ($e > $ma_32bit_23mantissa) {
66 0         0 warn "Machine accuracy ($e greater than $ma_32bit_23mantissa) "
67             . "seems worse than the primitive 32-bit double representation. "
68             . "Setting to minimum accuracy of $ma_32bit_23mantissa.";
69 0         0 return $ma_32bit_23mantissa;
70             }
71              
72 1         1 $epsilon = $e;
73              
74 1         2 return $e;
75             }
76              
77             =head1 AUTHOR
78              
79             binary.com, C<< >>
80              
81             =head1 BUGS
82              
83             Please report any bugs or feature requests to C, or through
84             the web interface at L. I will be notified, and then you'll
85             automatically be notified of progress on your bug as I make changes.
86              
87              
88             =head1 SUPPORT
89              
90             You can find documentation for this module with the perldoc command.
91              
92             perldoc Machine::Epsilon
93              
94              
95             You can also look for information at:
96              
97             =over 4
98              
99             =item * RT: CPAN's request tracker (report bugs here)
100              
101             L
102              
103             =item * AnnoCPAN: Annotated CPAN documentation
104              
105             L
106              
107             =item * CPAN Ratings
108              
109             L
110              
111             =item * Search CPAN
112              
113             L
114              
115             =back
116              
117             =head1 REFERENCES
118              
119             http://en.wikipedia.org/wiki/Machine_epsilon
120              
121             =head1 LICENSE AND COPYRIGHT
122              
123             Copyright 2014 binary.com.
124              
125             This program is free software; you can redistribute it and/or modify it
126             under the terms of either: the GNU General Public License as published
127             by the Free Software Foundation; or the Artistic License.
128              
129             See L for more information.
130              
131              
132             =cut
133              
134             1; # End of Machine::Epsilon
135