File Coverage

blib/lib/Math/Round/SignificantFigures.pm
Criterion Covered Total %
statement 31 31 100.0
branch 8 8 100.0
condition 4 4 100.0
subroutine 10 10 100.0
pod 6 6 100.0
total 59 59 100.0


line stmt bran cond sub pod time code
1             package Math::Round::SignificantFigures;
2 5     5   290350 use strict;
  5         46  
  5         124  
3 5     5   21 use warnings;
  5         13  
  5         156  
4 5     5   2088 use POSIX qw{ceil floor};
  5         27104  
  5         22  
5             require Exporter;
6              
7             our $VERSION = '0.01';
8             our @ISA = qw(Exporter);
9             my @figs = qw{roundsigfigs ceilsigfigs floorsigfigs};
10             my @digs = qw{roundsigdigs ceilsigdigs floorsigdigs};
11             our %EXPORT_TAGS = (
12             figs => \@figs,
13             digs => \@digs,
14             all => [@figs, @digs],
15             );
16             our @EXPORT_OK = (@figs, @digs);
17             our @EXPORT = qw{};
18              
19             =head1 NAME
20              
21             Math::Round::SignificantFigures - Perl package for rounding numbers to a specified number of Significant Figures
22              
23             =head1 SYNOPSIS
24              
25             use Math::Round::SignificantFigures qw{roundsigfigs};
26             print roundsigfigs(555.555, 3), "\n";
27              
28             =head1 DESCRIPTION
29              
30              
31             Math::Round::SignificantFigures supplies functions that will round numbers based on significant figures.
32              
33             This package spans the controversy whether people prefer to call significant figures or significant digits. You may export either or both but, I called the package significant figures since that is the page for Wikipedia.
34              
35             =head1 FUNCTIONS
36              
37             The exporter group :figs exports the roundsigfigs, ceilsigfigs, floorsigfigs functions. The exporter group :digs exports the roundsigdigs, ceilsigdigs, floorsigdigs functions. The exporter group :all exports all six functions
38              
39             =cut
40              
41             #head2 _floor_or_ceil_by_significant_digits
42             #
43             #The function _floor_or_ceil_by_significant_digits was mostly gleaned from https://stackoverflow.com/questions/202302/rounding-to-an-arbitrary-number-of-significant-digits. The function roundToSignificantFigures code sample appears to be in the public domain.
44             #
45             #cut
46              
47             sub _floor_or_ceil_by_significant_figures {
48 40     40   60 my $num = shift;
49 40   100     89 my $sigfigs = shift || 3; #undef default and zero does not make any sense
50 40   100     107 my $ceiling = shift || 0; #-1 floor, 0 round, 1 ceil
51 40 100       104 return $num if $num == 0;
52 39 100       77 my $half = $num < 0 ? -0.5 : 0.5;
53 39         179 my $d = ceil(log(abs($num))/log(10));
54 39         77 my $power = $sigfigs - $d;
55 39         73 my $magnitude = 10 ** $power;
56 39 100       120 my $shifted = $ceiling > 0 ? ceil($num * $magnitude)
    100          
57             : $ceiling < 0 ? floor($num * $magnitude)
58             : int($num * $magnitude + $half); #round
59 39         154 return $shifted / $magnitude;
60             }
61              
62             =head2 roundsigfigs, roundsigdigs
63              
64             Rounds a number given the number and a number of significant figures.
65              
66             =cut
67              
68             sub roundsigfigs {
69 23     23 1 738 my $num = shift;
70 23         32 my $sigfigs = shift;
71 23         52 return _floor_or_ceil_by_significant_figures($num, $sigfigs, 0);
72             }
73              
74 8     8 1 584 sub roundsigdigs {roundsigfigs(@_)};
75              
76             =head2 floorsigfigs, floorsigdigs
77              
78             Rounds a number toward -inf given the number and a number of significant figures.
79              
80             =cut
81              
82             sub floorsigfigs {
83 8     8 1 22 my $num = shift;
84 8         17 my $sigfigs = shift;
85 8         19 return _floor_or_ceil_by_significant_figures($num, $sigfigs, -1);
86             }
87              
88 4     4 1 9 sub floorsigdigs {floorsigfigs(@_)};
89              
90             =head2 ceilsigfigs, ceilsigdigs
91              
92             Rounds a number toward +inf given the number and a number of significant figures.
93              
94             =cut
95              
96             sub ceilsigfigs {
97 9     9 1 16 my $num = shift;
98 9         16 my $sigfigs = shift;
99 9         40 return _floor_or_ceil_by_significant_figures($num, $sigfigs, 1);
100             }
101              
102 4     4 1 9 sub ceilsigdigs {ceilsigfigs(@_)};
103              
104             =head1 SEE ALSO
105              
106             L supplies functions that will round numbers in different ways.
107              
108             L allows you to edit numbers to a significant number of digits.
109              
110             L
111              
112             L
113              
114             =head1 AUTHOR
115              
116             Michael R. Davis, MRDVT
117              
118             =head1 COPYRIGHT AND LICENSE
119              
120             MIT LICENSE
121              
122             Copyright (C) 2022 by Michael R. Davis
123              
124             =cut
125              
126             1;