From 8c985a4419c28a779fb76abe5a404553a677a62b Mon Sep 17 00:00:00 2001 From: P. J. McDermott Date: Sat, 28 Jan 2017 15:01:43 -0500 Subject: dfmt(): New function --- 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 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. @@ -133,9 +149,9 @@ zero" and "decimal round (away) from zero". =head1 THEORY The binary operation functions (C and C) operate on two numbers, -C and C. And obviously the unary operation functions (C and -C) operate on one number, C. The binary operation functions produce -a resulting number, C. +C and C. And obviously the unary operation functions (C, +C, and C) operate on one number, C. The binary operation +functions produce a resulting number, C. The input numbers C and C are broken into their integer (C) and fractional (C) parts, for example C<$ai> and C<$af>. All three numbers C, @@ -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 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. 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). +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 or C and format them +with C. =head1 AUTHOR -- cgit v0.9.1