summaryrefslogtreecommitdiffstats
path: root/lib/Math/Decimal/FastPP.pm
diff options
context:
space:
mode:
authorP. J. McDermott <pj@pehjota.net>2017-01-28 15:01:43 (EST)
committer P. J. McDermott <pj@pehjota.net>2017-01-28 15:26:44 (EST)
commit8c985a4419c28a779fb76abe5a404553a677a62b (patch)
tree651677928197b4f2bd6a4b2e76ea00f8af99b5dd /lib/Math/Decimal/FastPP.pm
parent343cb59004daa64d69e349c4f435a65ef5bf88af (diff)
downloadMath-Decimal-FastPP-8c985a4419c28a779fb76abe5a404553a677a62b.zip
Math-Decimal-FastPP-8c985a4419c28a779fb76abe5a404553a677a62b.tar.gz
Math-Decimal-FastPP-8c985a4419c28a779fb76abe5a404553a677a62b.tar.bz2
dfmt(): New function
Diffstat (limited to 'lib/Math/Decimal/FastPP.pm')
-rw-r--r--lib/Math/Decimal/FastPP.pm58
1 files changed, 47 insertions, 11 deletions
diff --git a/lib/Math/Decimal/FastPP.pm b/lib/Math/Decimal/FastPP.pm
index 538fb92..0f9960d 100644
--- a/lib/Math/Decimal/FastPP.pm
+++ b/lib/Math/Decimal/FastPP.pm
@@ -4,7 +4,7 @@ use strict;
use warnings;
use Exporter qw(import);
-our @EXPORT_OK = qw(dadd dmul drhtz drhfz);
+our @EXPORT_OK = qw(dadd dmul drhtz drhfz dfmt);
our $VERSION = '0.001';
@@ -83,6 +83,21 @@ sub drhfz
substr($as, length($as) - $_[1]);
}
+sub dfmt
+{
+ my ($a, $p) = @_;
+ my $s;
+ my $i;
+ my $f;
+ my $l;
+
+ ($s, $i, $f) = $a =~ m/^(-?)(\d*).?(\d*)$/;
+ $l = length($f);
+ if ($i eq "") { $i = "0"; }
+ if ($l < $p) { $f .= "0" x ($p - $l); }
+ return $s . $i . "." . $f;
+}
+
1;
__END__
@@ -97,11 +112,12 @@ Math::Decimal::FastPP - Fast pure-Perl decimal math
=head1 SYNOPSIS
- use Math::Decimal::FastPP qw(dadd dmul drhtz drhfz);
+ use Math::Decimal::FastPP qw(dadd dmul drhtz drhfz dfmt);
$a = dadd($a, "1.23"); # $a += 1.23
$c = dmul($a, $b); # $c = $a * $b
$a = drhtz($a); # Round half toward zero
+ $a = dfmt($a, 2); # Format with leading/trailing zeroes as needed
=head1 DESCRIPTION
@@ -111,8 +127,8 @@ built-in binary floating-point math, but they're faster than
L<Math::BigFloat|Math::BigFloat> and other commonly used decimal math modules.
This module is currently less complete than Perl's built-in math and other
-decimal math modules. So far it only includes addition, multiplication, and two
-rounding functions.
+decimal math modules. So far it only includes addition, multiplication, two
+rounding functions, and one formatting function.
Despite the similar name and purpose, this module is not compatible with
L<Math::Decimal|Math::Decimal>.
@@ -133,9 +149,9 @@ zero" and "decimal round (away) from zero".
=head1 THEORY
The binary operation functions (C<dadd()> and C<dmul()>) operate on two numbers,
-C<a> and C<b>. And obviously the unary operation functions (C<drhtz()> and
-C<drhfz()>) operate on one number, C<a>. The binary operation functions produce
-a resulting number, C<c>.
+C<a> and C<b>. And obviously the unary operation functions (C<drhtz()>,
+C<drhfz()>, and C<dfmt()>) operate on one number, C<a>. The binary operation
+functions produce a resulting number, C<c>.
The input numbers C<a> and C<b> are broken into their integer (C<i>) and
fractional (C<f>) parts, for example C<$ai> and C<$af>. All three numbers C<a>,
@@ -203,6 +219,26 @@ example:
C<$p> is a non-negative (i.e. zero or positive) integer representing the number
of significant digits right of the radix point.
+=head2 dfmt()
+
+ $a = dfmt($a, $p);
+
+Formats C<$a> with precision C<$p>. Ensures that C<$a> has a leading zero if
+its absolute value is less than 1 and ensures that C<$a> has at least C<$p>
+digits in its fractional part. For example:
+
+ dfmt("2.3", 2); # Returns "2.30"
+ dfmt(".23", 2); # Returns "0.23"
+
+C<$p> is a non-negative (i.e. zero or positive) integer representing the number
+of significant digits right of the radix point.
+
+The following two lines are equivalent, except that C<dfmt()> safely operates on
+C<$a> as a string instead of as a floating-point number:
+
+ $a = dfmt($a, $p);
+ $a = sprintf("%0.${p}f", $a);
+
=head1 DIAGNOSTICS
This module has no diagnostics.
@@ -226,10 +262,10 @@ L<Math::Decimal|Math::Decimal>.
These arithmetic functions preserve all significant fractional digits, including
trailing zeroes. They also don't always add a leading zero before the radix
point for numbers with absolute values less than one. So the output numbers can
-look "ugly", like ".123000". This is only an issue if the numbers (which are
-returned as strings) are concatenated into other strings or printed without
-formatting. If this is an issue in your code, use the outputs as numbers (e.g.
-C<$c + 0>) or print with formatting (with C<printf>).
+look "ugly", like ".123000". This is only an issue when the numbers (which are
+returned as strings) are concatenated into other strings or printed. In these
+cases, you can round the numbers with C<drhtz()> or C<drhfz()> and format them
+with C<dfmt()>.
=head1 AUTHOR