NAME

Math::Decimal - arithmetic in decimal

SYNOPSIS

use Math::Decimal qw(\$dec_number_rx);

if(\$arg =~ /\A\$dec_number_rx\z/o) { ...
# and other regular expressions

use Math::Decimal qw(is_dec_number check_dec_number);

if(is_dec_number(\$arg)) { ...
check_dec_number(\$arg);

use Math::Decimal qw(dec_canonise);

\$r = dec_canonise(\$a);

use Math::Decimal qw(
dec_sgn dec_abs
dec_cmp dec_min dec_max
dec_pow10 dec_mul_pow10
dec_mul
dec_rndiv_and_rem dec_rndiv
dec_round_and_rem dec_round
dec_rem);

\$v = dec_sgn(\$a);
\$v = dec_abs(\$a);
@v = sort { dec_cmp(\$a, \$b) } @a;
\$v = dec_min(\$a, \$b);
\$v = dec_max(\$a, \$b);
\$v = dec_neg(\$a);
\$v = dec_add(\$a, \$b);
\$v = dec_sub(\$a, \$b);
\$v = dec_pow10(\$a);
\$v = dec_mul_pow10(\$a, \$b);
\$v = dec_mul(\$a, \$b);
(\$q, \$r) = dec_rndiv_and_rem("NEAR_EVN", \$a, \$b);
\$q = dec_rndiv("NEAR_EVN", \$a, \$b);
(\$v, \$r) = dec_round_and_rem("NEAR_EVN", \$a, \$b);
\$v = dec_round("NEAR_EVN", \$a, \$b);
\$r = dec_rem("NEAR_EVN", \$a, \$b);

DESCRIPTION

This module performs basic arithmetic with arbitrary-precision numbers expressed in decimal in ordinary Perl strings. The numbers can be arbitrarily large, and can involve arbitrarily small fractions, and all results are exact. This differs from Perl's standard arithmetic, which is limited-precision binary (floating point) arithmetic. However, because Perl performs implicit conversions between strings and numbers, using decimal in the string form, it is extremely easy to exchange values between this module and Perl's native arithmetic.

Although Perl's scalars have space to store a number directly, that is not used here. This module operates only on the string part of scalars, ignoring the Perlish numerics entirely. It is not confused by dualvars (scalars with independent string and number values).

Numbers are represented in strings in a simple format, consisting of optional sign, one or more integer digits, then optionally a dot (for the decimal point) and one or more fractional digits. All representable numbers have infinitely many acceptable representations (by adding leading and trailing zero digits). The functions of this module consistently return numbers in their shortest possible form.

This module is intended for situations where exact numeric behaviour is important, and Perl's default arithmetic is inadequate because fractions or large numbers are involved, but the arithmetic makes up only a small part of the program's behaviour. In those situations, it is convenient that the functions here operate directly on strings that are useful elsewhere in the program. If arithmetic is a large part of the program, it will probably be better to use specialised (non-string) numeric object types, such as those of Math::GMP. These objects are less convenient for interoperation, but arithmetic with them is more efficient.

If you need to represent arbitrary (non-decimal) fractions exactly, such as 1/3, then this module is not suitable. In that case you need a general rational arithmetic module, such as Math::BigRat. Be prepared to pay a large performance penalty for it.

Most of this module is implemented in XS, with a pure Perl backup version for systems that can't handle XS.

THEORY

The numbers processed by this module, the decimals, are those of the form M * 10^-E, where M is an integer and E is a non-negative integer, with range otherwise unlimited. (For any such number there are actually an infinite number of possible (M, E) tuples: if a certain E value is possible then all greater integers are also possible E values.) It is an infinite set of cardinality aleph-0 (although this implementation is hampered by the finiteness of computer memory). The set includes both positive and negative numbers, and zero. It is a proper superset of the integers, and a proper subset of the rationals. There are no infinite numbers, nulls, irrationals, non-real complex numbers, or signed zeroes.

Like the set of integers, the set of decimals is closed under mathematical addition, subtraction, and multiplication. It thus forms a commutative ring (in fact, an integral domain). Unlike the set of rationals, it is not closed under exact division, and so it does not form a field.

The arithmetic operations supplied by this module are those of ordinary mathematical arithmetic. They thus obey the usual identities, such as associativity (of addition and multiplication) and cancellation laws. (This is unlike floating point arithmetic. Any system of floating point numbers is not closed under mathematical addition, for example, but by construction it is closed under floating point addition, which necessarily differs from mathematical addition. Floating point addition does not obey associativity or cancellation laws.)

ROUNDING MODES

For rounding division operations, a rounding mode must be specified. It is given as a short string, which may be any of these:

TWZ

towards zero

AWZ

away from zero

FLR

floor: downwards (toward negative infinity)

CLG

ceiling: upwards (toward positive infinity)

EVN

to even

ODD

to odd

NEAR_MODE

to nearest, breaking ties according to MODE (which must be one of the six above)

EXACT

die if any rounding is required

The mode "NEAR_EVN" (rounding to nearest, breaking ties to the even number), commonly known as "bankers' rounding", is usually the best for general rounding purposes.

REGULAR EXPRESSIONS

Each of these regular expressions matches some subset of numbers, in the string form used by this module. The regular expressions do not include any anchors, so to check whether an entire string matches a number format you must supply the anchors yourself.

\$dec_number_rx

Any number processed by this module. This checks the syntax in which the number is expressed, without restricting its numeric value. The number syntax consists of optional sign, one or more integer digits, then optionally a dot (for the decimal point) and one or more fractional digits. It is not permitted to have no integer digits, nor to have no fractional digits if there is a decimal point. All digits must be ASCII decimal digits. Unlike Perl's standard string-to-number conversions, whitespace and other non-numeric parts are not permitted.

\$dec_integer_rx

Any integer. This recognises integer values expressed in the decimal format used by this module, not an integer-specific format. So fractional decimal digits are allowed, provided that they are all zero, as in "123.000".

\$dec_zero_rx

Zero. This may have arbitrarily many integer and fractional digits, and may be expressed with either sign.

\$dec_one_rx

Positive one.

\$dec_negone_rx

Negative one.

FUNCTIONS

Each dec_ function takes one or more decimal arguments (A, B) to operate on. If these arguments are not valid decimal numbers then the function will die. Results are always returned as decimals in minimum-length (canonical) form.

Classification

is_dec_number(ARG)

Returns a truth value indicating whether ARG is a plain string satisfying the decimal number syntax.

check_dec_number(ARG)

Checks whether ARG is a plain string satisfying the decimal number syntax. Returns normally if it is. dies if it is not.

Representation

dec_canonise(A)

This returns the value A, numerically unmodified, but expressed in minimum-length (canonical) form. Numerically this is the identity function.

Arithmetic

dec_sgn(A)

Returns +1 if the argument is positive, 0 if the argument is zero, or -1 if the argument is negative.

The value returned is not just a string, as usual for this module, but has also been subjected to Perl's implicit numerification. This is necessary for it to be an acceptable comparison value in a sort operation, on Perls prior to 5.11.0, due to perl bug #69384.

dec_abs(A)

Absolute value (magnitude, discarding sign).

dec_cmp(A, B)

Arithmetic comparison. Returns -1, 0, or +1, indicating whether A is less than, equal to, or greater than B.

The value returned is not just a string, as usual for this module, but has also been subjected to Perl's implicit numerification. This is necessary for it to be an acceptable comparison value in a sort operation, on Perls prior to 5.11.0, due to perl bug #69384.

dec_min(A, B)

Arithmetic minimum. Returns the arithmetically lesser of the two arguments.

dec_max(A, B)

Arithmetic maximum. Returns the arithmetically greater of the two arguments.

dec_neg(A)

Negation: returns -A.

Addition: returns A + B.

dec_sub(A, B)

Subtraction: returns A - B.

dec_pow10(A)

Power of ten: returns 10^A. A must be an integer value (though it has the usual decimal syntax). dies if A is too large for Perl to handle the result.

dec_mul_pow10(A, B)

Digit shifting: returns A * 10^B. B must be an integer value (though it has the usual decimal syntax). dies if B is too large for Perl to handle the result.

dec_mul(A, B)

Multiplication: returns A * B.

dec_rndiv_and_rem(MODE, A, B)

Rounding division: returns a list of two items, the quotient (Q) and remainder (R) from the division of A by B. The quotient is by definition integral, and the quantities are related by the equation Q*B + R = A. MODE controls the rounding mode, which determines which integer Q is when R is non-zero.

dec_rndiv(MODE, A, B)

Rounding division: returns the quotient (Q) from the division of A by B. The quotient is by definition integral, and approximates A/B. MODE controls the rounding mode, which determines which integer Q is when it can't be exactly A/B.

dec_round_and_rem(MODE, A, B)

Rounding: returns a list of two items, the rounded value (V) and remainder (R) from the rounding of A to a multiple of B. The rounded value is an exact multiple of B, and the quantities are related by the equation V + R = A. MODE controls the rounding mode, which determines which multiple of B V is when R is non-zero.

dec_round(MODE, A, B)

Rounding: returns the rounded value (V) from the rounding of A to a multiple of B. The rounded value is an exact multiple of B, and approximates A. MODE controls the rounding mode, which determines which multiple of B V is when it can't be exactly A.

dec_rem(MODE, A, B)

Remainder: returns the remainder (R) from the division of A by B. R differs from A by an exact multiple of B. MODE controls the rounding mode, which determines which quotient is used when R is non-zero.

BUGS

The implementation of division is hideously inefficient. This should be improved in a future version.