Math-Round-SignificantFigures
view release on metacpan or search on metacpan
lib/Math/Round/SignificantFigures.pm view on Meta::CPAN
package Math::Round::SignificantFigures;
use strict;
use warnings;
use POSIX qw{ceil floor log10};
require Exporter;
our $VERSION = '0.02';
our @ISA = qw(Exporter);
my @figs = qw{roundsigfigs ceilsigfigs floorsigfigs};
my @digs = qw{roundsigdigs ceilsigdigs floorsigdigs};
our %EXPORT_TAGS = (
figs => \@figs,
digs => \@digs,
all => [@figs, @digs],
);
our @EXPORT_OK = (@figs, @digs);
our @EXPORT = qw{};
=head1 NAME
Math::Round::SignificantFigures - Perl package for rounding numbers to a specified number of Significant Figures
=head1 SYNOPSIS
use Math::Round::SignificantFigures qw{roundsigfigs};
print roundsigfigs(555.555, 3), "\n";
=head1 DESCRIPTION
Math::Round::SignificantFigures supplies functions that will round numbers based on significant figures.
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.
=head1 FUNCTIONS
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
=cut
#head2 _floor_or_ceil_by_significant_digits
#
#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 publ...
#
#cut
sub _floor_or_ceil_by_significant_figures {
my $num = shift;
my $sigfigs = shift || 3; #undef default and zero does not make any sense
my $ceiling = shift || 0; #-1 floor, 0 round, 1 ceil
return $num if $num == 0;
my $half = $num < 0 ? -0.5 : 0.5;
my $d = ceil(log10(abs($num)));
my $power = $sigfigs - $d;
my $magnitude = 10 ** $power;
my $shifted = $ceiling > 0 ? ceil($num * $magnitude)
: $ceiling < 0 ? floor($num * $magnitude)
: int($num * $magnitude + $half); #round
return $shifted / $magnitude;
}
=head2 roundsigfigs, roundsigdigs
Rounds a number given the number and a number of significant figures.
=cut
sub roundsigfigs {
my $num = shift;
my $sigfigs = shift;
return _floor_or_ceil_by_significant_figures($num, $sigfigs, 0);
}
sub roundsigdigs {roundsigfigs(@_)};
=head2 floorsigfigs, floorsigdigs
Rounds a number toward -inf given the number and a number of significant figures.
=cut
sub floorsigfigs {
my $num = shift;
my $sigfigs = shift;
return _floor_or_ceil_by_significant_figures($num, $sigfigs, -1);
}
sub floorsigdigs {floorsigfigs(@_)};
=head2 ceilsigfigs, ceilsigdigs
Rounds a number toward +inf given the number and a number of significant figures.
=cut
sub ceilsigfigs {
my $num = shift;
my $sigfigs = shift;
return _floor_or_ceil_by_significant_figures($num, $sigfigs, 1);
}
sub ceilsigdigs {ceilsigfigs(@_)};
=head1 SEE ALSO
L<Math::Round> supplies functions that will round numbers in different ways.
L<Math::SigDig> allows you to edit numbers to a significant number of digits.
L<https://en.wikipedia.org/wiki/Significant_figures#Rounding_to_significant_figures>
L<https://stackoverflow.com/questions/202302/rounding-to-an-arbitrary-number-of-significant-digits>
=head1 AUTHOR
Michael R. Davis, MRDVT
=head1 COPYRIGHT AND LICENSE
MIT LICENSE
Copyright (C) 2022 by Michael R. Davis
=cut
1;
( run in 0.976 second using v1.01-cache-2.11-cpan-71847e10f99 )