-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | An implementation of the General Decimal Arithmetic
-- Specification
--
-- This package provides an implementation of the General Decimal
-- Arithmetic Specification by Mike Cowlishaw.
--
-- For details, see http://speleotrove.com/decimal/
@package decimal-arithmetic
@version 0.5.0.0
-- | It is not usually necessary to import this module unless you want to
-- use the arithmetic operations from Numeric.Decimal.Operation or
-- you need precise control over the handling of exceptional conditions
-- in an arithmetic computation.
module Numeric.Decimal.Arithmetic
-- | A context for decimal arithmetic, carrying signal flags, trap enabler
-- state, and a trap handler, parameterized by precision p and
-- rounding mode r
data Context p r
-- | Return a new context with all signal flags cleared and all traps
-- disabled.
newContext :: Context p r
-- | The current signal flags of the context
flags :: Context p r -> Signals
-- | Return the precision of the arithmetic context (or Nothing if
-- the precision is infinite).
getPrecision :: Precision p => Arith p r (Maybe Int)
-- | Return the rounding mode of the arithmetic context.
getRounding :: Rounding r => Arith p r RoundingAlgorithm
-- | A value representation of a rounding algorithm (cf. Rounding).
data RoundingAlgorithm
RoundDown :: RoundingAlgorithm
RoundHalfUp :: RoundingAlgorithm
RoundHalfEven :: RoundingAlgorithm
RoundCeiling :: RoundingAlgorithm
RoundFloor :: RoundingAlgorithm
RoundHalfDown :: RoundingAlgorithm
RoundUp :: RoundingAlgorithm
Round05Up :: RoundingAlgorithm
-- | Return a new context with all signal flags cleared, all traps enabled
-- except for Inexact, Rounded, and Subnormal, using
-- a precision of 9 significant decimal digits, and rounding half up.
-- Trapped signals simply call throwError with the corresponding
-- Exception, and can be caught using catchError.
basicDefaultContext :: Context P9 RoundHalfUp
-- | Return a new context with all signal flags cleared, all traps disabled
-- (IEEE 854 §7), using selectable precision, and rounding half even
-- (IEEE 754 §4.3.3).
extendedDefaultContext :: Context p RoundHalfEven
-- | A decimal arithmetic monad parameterized by the precision p
-- and rounding mode r
data Arith p r a
-- | Evaluate an arithmetic computation in the given context and return the
-- final value (or exception) and resulting context.
runArith :: Arith p r a -> Context p r -> (Either (Exception p r) a, Context p r)
-- | Evaluate an arithmetic computation in the given context and return the
-- final value or exception, discarding the resulting context.
evalArith :: Arith p r a -> Context p r -> Either (Exception p r) a
-- | Perform a subcomputation using a different precision and/or rounding
-- mode. The subcomputation is evaluated within a new context with all
-- flags cleared and all traps disabled. Any flags set in the context of
-- the subcomputation are ignored, but if an exception is returned it
-- will be re-raised within the current context.
subArith :: Arith a b (Decimal a b) -> Arith p r (Decimal a b)
-- | A representation of an exceptional condition
data Exception p r
-- | The signal raised by the exceptional condition
exceptionSignal :: Exception p r -> Signal
-- | The defined result for the exceptional condition
exceptionResult :: Exception p r -> Decimal p r
data Signal
-- | Raised when the exponent of a result has been altered or constrained
-- in order to fit the constraints of a specific concrete representation
Clamped :: Signal
-- | Raised when a non-zero dividend is divided by zero
DivisionByZero :: Signal
-- | Raised when a result is not exact (one or more non-zero coefficient
-- digits were discarded during rounding)
Inexact :: Signal
-- | Raised when a result would be undefined or impossible
InvalidOperation :: Signal
-- | Raised when the exponent of a result is too large to be represented
Overflow :: Signal
-- | Raised when a result has been rounded (that is, some zero or non-zero
-- coefficient digits were discarded)
Rounded :: Signal
-- | Raised when a result is subnormal (its adjusted exponent is less than
-- Emin), before any rounding
Subnormal :: Signal
-- | Raised when a result is both subnormal and inexact
Underflow :: Signal
-- | A group of signals can be manipulated as a set.
data Signals
-- | Create a set of signals from a singleton.
signal :: Signal -> Signals
-- | Create a set of signals from a list.
signals :: [Signal] -> Signals
-- | A set containing every signal
allSignals :: Signals
-- | Determine whether a signal is a member of a set.
signalMember :: Signal -> Signals -> Bool
-- | Set the given signal flag in the context of the current arithmetic
-- computation, and call the trap handler if the trap for this signal is
-- currently enabled.
raiseSignal :: Signal -> Decimal p r -> Arith p r (Decimal p r)
-- | Clear the given signal flags from the context of the current
-- arithmetic computation.
clearFlags :: Signals -> Arith p r ()
-- | A trap handler function may return a substitute result for the
-- operation that caused the exceptional condition, or it may call
-- throwError to pass control to an enclosing catchError
-- handler (or abort the arithmetic computation).
type TrapHandler p r = Exception p r -> Arith p r (Decimal p r)
-- | Evaluate an arithmetic computation within a modified context that
-- enables the given signals to be trapped by the given handler. The
-- previous trap handler (and enabler state) will be restored during any
-- trap, as well as upon completion. Any existing trap handlers for
-- signals not mentioned remain in effect.
trap :: Signals -> TrapHandler p r -> Arith p r a -> Arith p r a
instance GHC.Show.Show (Numeric.Decimal.Arithmetic.Exception p r)
instance GHC.Classes.Eq Numeric.Decimal.Arithmetic.Signals
instance GHC.Show.Show Numeric.Decimal.Arithmetic.Signal
instance GHC.Enum.Bounded Numeric.Decimal.Arithmetic.Signal
instance GHC.Enum.Enum Numeric.Decimal.Arithmetic.Signal
instance GHC.Classes.Eq Numeric.Decimal.Arithmetic.Signal
instance GHC.Base.Functor (Numeric.Decimal.Arithmetic.Arith p r)
instance GHC.Base.Applicative (Numeric.Decimal.Arithmetic.Arith p r)
instance GHC.Base.Monad (Numeric.Decimal.Arithmetic.Arith p r)
instance Control.Monad.Error.Class.MonadError (Numeric.Decimal.Arithmetic.Exception p r) (Numeric.Decimal.Arithmetic.Arith p r)
instance Control.Monad.State.Class.MonadState (Numeric.Decimal.Arithmetic.Context p r) (Numeric.Decimal.Arithmetic.Arith p r)
instance GHC.Show.Show Numeric.Decimal.Arithmetic.Signals
instance GHC.Base.Monoid Numeric.Decimal.Arithmetic.Signals
-- | The functions in this module implement conversions between
-- Decimal and String as described in the General
-- Decimal Arithmetic Specification.
--
-- Because these functions are also used to implement Show and
-- Read class methods, it is not usually necessary to import this
-- module except to use the toEngineeringString function.
module Numeric.Decimal.Conversion
-- | Convert a number to a string, using scientific notation if an exponent
-- is needed.
toScientificString :: Decimal p r -> ShowS
-- | Convert a number to a string, using engineering notation if an
-- exponent is needed.
toEngineeringString :: Decimal p r -> ShowS
-- | Convert a string to a number, as defined by its abstract
-- representation. The string is expected to conform to the numeric
-- string syntax described here.
toNumber :: ReadP (Decimal PInfinite r)
-- | This module implements the decimal interchange format encodings
-- described in IEEE 754-2008, including the decimal32,
-- decimal64, and decimal128 formats, as well as arbitrary
-- width decimal{k} formats through the use of Format with
-- KPlus32 and/or KTimes2. For example, to use a
-- decimal96 format:
--
--
-- type Decimal96 = ExtendedDecimal (Format (KPlus32 K64) DecimalCoefficient)
--
--
-- Currently only a decimal encoding of coefficients is implemented, but
-- a binary encoding may be added in the future.
module Numeric.Decimal.Encoding
-- | A decimal floating point number with 7 digits of precision, rounding
-- half even, and a 32-bit encoded representation using the
-- decimal32 interchange format (with a decimal encoding for the
-- coefficient)
type Decimal32 = ExtendedDecimal Pdecimal32
-- | A decimal floating point number with 16 digits of precision, rounding
-- half even, and a 64-bit encoded representation using the
-- decimal64 interchange format (with a decimal encoding for the
-- coefficient)
type Decimal64 = ExtendedDecimal Pdecimal64
-- | A decimal floating point number with 34 digits of precision, rounding
-- half even, and a 128-bit encoded representation using the
-- decimal128 interchange format (with a decimal encoding for the
-- coefficient)
type Decimal128 = ExtendedDecimal Pdecimal128
-- | A type with Precision instance specifying decimal32
-- interchange format parameters (using a decimal encoding for the
-- coefficient) having an effective precision of 7 decimal digits
type Pdecimal32 = Format K32 DecimalCoefficient
-- | A type with Precision instance specifying decimal64
-- interchange format parameters (using a decimal encoding for the
-- coefficient) having an effective precision of 16 decimal digits
type Pdecimal64 = Format K64 DecimalCoefficient
-- | A type with Precision instance specifying decimal128
-- interchange format parameters (using a decimal encoding for the
-- coefficient) having an effective precision of 34 decimal digits
type Pdecimal128 = Format K128 DecimalCoefficient
-- | A type (with a Precision instance) for specifying interchange
-- format parameters k and coefficient encoding c
data Format k c
-- | Interchange format parameters used to define an encoding and derive
-- the format's precision and Emax
class Parameters k
-- | Parameters for the decimal32 interchange format
data K32
-- | Parameters for the decimal64 interchange format
type K64 = KPlus32 K32
-- | Parameters for the decimal128 interchange format
type K128 = KTimes2 K64
-- | Parameters for a decimal{k + 32} interchange format
data KPlus32 k
-- | Parameters for a decimal{k × 2} interchange format
data KTimes2 k
-- | Specify a decimal encoding for the coefficient.
data DecimalCoefficient
-- | Specify a binary encoding for the coefficient (currently
-- unimplemented).
data BinaryCoefficient
instance Numeric.Decimal.Encoding.Parameters Numeric.Decimal.Encoding.K32
instance Numeric.Decimal.Encoding.Parameters k => Numeric.Decimal.Encoding.Parameters (Numeric.Decimal.Encoding.KPlus32 k)
instance Numeric.Decimal.Encoding.Parameters k => Numeric.Decimal.Encoding.Parameters (Numeric.Decimal.Encoding.KTimes2 k)
instance Numeric.Decimal.Encoding.CoefficientEncoding Numeric.Decimal.Encoding.DecimalCoefficient
instance Numeric.Decimal.Encoding.CoefficientEncoding Numeric.Decimal.Encoding.BinaryCoefficient
instance Numeric.Decimal.Encoding.Parameters k => Numeric.Decimal.Precision.Precision (Numeric.Decimal.Encoding.Format k c)
instance Numeric.Decimal.Encoding.Parameters k => Numeric.Decimal.Precision.FinitePrecision (Numeric.Decimal.Encoding.Format k c)
instance Numeric.Decimal.Encoding.Parameters k => Data.Binary.Class.Binary (Numeric.Decimal.Number.Decimal (Numeric.Decimal.Encoding.Format k Numeric.Decimal.Encoding.DecimalCoefficient) r)
-- | The operations described in the General Decimal Arithmetic
-- Specification are provided here.
--
-- It is suggested to import this module qualified to avoid
-- Prelude name clashes:
--
--
-- import qualified Numeric.Decimal.Operation as Op
--
--
-- Note that it is not usually necessary to import this module unless you
-- want to use operations unavailable through class methods, or you need
-- precise control over the handling of exceptional conditions. (See also
-- Numeric.Decimal.Arithmetic.)
module Numeric.Decimal.Operation
-- | add takes two operands. If either operand is a special
-- value then the general rules apply.
--
-- Otherwise, the operands are added.
--
-- The result is then rounded to precision digits if necessary,
-- counting from the most significant digit of the result.
add :: (Precision p, Rounding r) => Decimal a b -> Decimal c d -> Arith p r (Decimal p r)
-- | subtract takes two operands. If either operand is a special
-- value then the general rules apply.
--
-- Otherwise, the operands are added after inverting the sign used
-- for the second operand.
--
-- The result is then rounded to precision digits if necessary,
-- counting from the most significant digit of the result.
subtract :: (Precision p, Rounding r) => Decimal a b -> Decimal c d -> Arith p r (Decimal p r)
-- | multiply takes two operands. If either operand is a special
-- value then the general rules apply. Otherwise, the operands are
-- multiplied together (“long multiplication”), resulting in a number
-- which may be as long as the sum of the lengths of the two operands.
--
-- The result is then rounded to precision digits if necessary,
-- counting from the most significant digit of the result.
multiply :: (Precision p, Rounding r) => Decimal a b -> Decimal c d -> Arith p r (Decimal p r)
-- | divide takes two operands. If either operand is a special
-- value then the general rules apply.
--
-- Otherwise, if the divisor is zero then either the Division undefined
-- condition is raised (if the dividend is zero) and the result is NaN,
-- or the Division by zero condition is raised and the result is an
-- Infinity with a sign which is the exclusive or of the signs of
-- the operands.
--
-- Otherwise, a “long division” is effected.
--
-- The result is then rounded to precision digits, if necessary,
-- according to the rounding algorithm and taking into account the
-- remainder from the division.
divide :: (FinitePrecision p, Rounding r) => Decimal a b -> Decimal c d -> Arith p r (Decimal p r)
-- | power takes two operands, and raises a number (the left-hand
-- operand) to a power (the right-hand operand). If either operand is a
-- special value then the general rules apply, except as stated
-- below.
--
-- The following rules apply:
--
--
-- - If both operands are zero, or if the left-hand operand is less
-- than zero and the right-hand operand does not have an integral value
-- or is infinite, an Invalid operation condition is raised, the result
-- is NaN, and the following rules do not apply.
-- - If the left-hand operand is infinite, the result will be exact and
-- will be infinite if the right-hand side is positive, 1 if the
-- right-hand side is a zero, and 0 if the right-hand side is
-- negative.
-- - If the left-hand operand is a zero, the result will be exact and
-- will be infinite if the right-hand side is negative or 0 if the
-- right-hand side is positive.
-- - If the right-hand operand is a zero, the result will be 1 and
-- exact.
-- - In cases not covered above, the result will be inexact unless the
-- right-hand side has an integral value and the result is finite and can
-- be expressed exactly within precision digits. In this latter
-- case, if the result is unrounded then its exponent will be that which
-- would result if the operation were calculated by repeated
-- multiplication (if the second operand is negative then the reciprocal
-- of the first operand is used, with the absolute value of the second
-- operand determining the multiplications).
-- - Inexact finite results should be correctly rounded, but may be up
-- to 1 ulp (unit in last place) in error.
-- - The sign of the result will be 1 only if the right-hand
-- side has an integral value and is odd (and is not infinite) and also
-- the sign of the left-hand side is 1. In all other cases, the
-- sign of the result will be 0.
--
power :: (FinitePrecision p, Rounding r) => Decimal a b -> Decimal c d -> Arith p r (Decimal p r)
-- | squareRoot takes one operand. If the operand is a special
-- value then the general rules apply.
--
-- Otherwise, the ideal exponent of the result is defined to be half the
-- exponent of the operand (rounded to an integer, towards −Infinity, if
-- necessary) and then:
--
-- If the operand is less than zero an Invalid operation condition is
-- raised.
--
-- If the operand is greater than zero, the result is the square root of
-- the operand. If no rounding is necessary (the exact result requires
-- precision digits or fewer) then the coefficient and exponent
-- giving the correct value and with the exponent closest to the ideal
-- exponent is used. If the result must be inexact, it is rounded using
-- the RoundHalfEven algorithm and the coefficient will have
-- exactly precision digits (unless the result is subnormal), and
-- the exponent will be set to maintain the correct value.
--
-- Otherwise (the operand is equal to zero), the result will be the zero
-- with the same sign as the operand and with the ideal exponent.
squareRoot :: FinitePrecision p => Decimal a b -> Arith p r (Decimal p RoundHalfEven)
-- | fusedMultiplyAdd takes three operands; the first two are
-- multiplied together, using multiply, with sufficient precision
-- and exponent range that the result is exact and unrounded. No
-- flags are set by the multiplication unless one of the first two
-- operands is a signaling NaN or one is a zero and the other is an
-- infinity.
--
-- Unless the multiplication failed, the third operand is then added to
-- the result of that multiplication, using add, under the current
-- context.
--
-- In other words, fusedMultiplyAdd x y z delivers a result
-- which is (x × y) + z with only the one, final, rounding.
fusedMultiplyAdd :: (Precision p, Rounding r) => Decimal a b -> Decimal c d -> Decimal e f -> Arith p r (Decimal p r)
-- | exp takes one operand. If the operand is a NaN then the general
-- rules for special values apply.
--
-- Otherwise, the result is e raised to the power of the operand,
-- with the following cases:
--
--
-- - If the operand is −Infinity, the result is 0 and exact.
-- - If the operand is a zero, the result is 1 and exact.
-- - If the operand is +Infinity, the result is +Infinity and
-- exact.
-- - Otherwise the result is inexact and will be rounded using the
-- RoundHalfEven algorithm. The coefficient will have exactly
-- precision digits (unless the result is subnormal). These
-- inexact results should be correctly rounded, but may be up to 1 ulp
-- (unit in last place) in error.
--
exp :: FinitePrecision p => Decimal a b -> Arith p r (Decimal p RoundHalfEven)
-- | ln takes one operand. If the operand is a NaN then the general
-- rules for special values apply.
--
-- Otherwise, the operand must be a zero or positive, and the result is
-- the natural (base e) logarithm of the operand, with the
-- following cases:
--
--
-- - If the operand is a zero, the result is −Infinity and exact.
-- - If the operand is +Infinity, the result is +Infinity and
-- exact.
-- - If the operand equals one, the result is 0 and exact.
-- - Otherwise the result is inexact and will be rounded using the
-- RoundHalfEven algorithm. The coefficient will have exactly
-- precision digits (unless the result is subnormal). These
-- inexact results should be correctly rounded, but may be up to 1 ulp
-- (unit in last place) in error.
--
ln :: FinitePrecision p => Decimal a b -> Arith p r (Decimal p RoundHalfEven)
-- | log10 takes one operand. If the operand is a NaN then the
-- general rules for special values apply.
--
-- Otherwise, the operand must be a zero or positive, and the result is
-- the base 10 logarithm of the operand, with the following cases:
--
--
-- - If the operand is a zero, the result is −Infinity and exact.
-- - If the operand is +Infinity, the result is +Infinity and
-- exact.
-- - If the operand equals an integral power of ten (including 10^0 and
-- negative powers) and there is sufficient precision to hold the
-- integral part of the result, the result is an integer (with an
-- exponent of 0) and exact.
-- - Otherwise the result is inexact and will be rounded using the
-- RoundHalfEven algorithm. The coefficient will have exactly
-- precision digits (unless the result is subnormal). These
-- inexact results should be correctly rounded, but may be up to 1 ulp
-- (unit in last place) in error.
--
log10 :: FinitePrecision p => Decimal a b -> Arith p r (Decimal p RoundHalfEven)
-- | plus takes one operand, and corresponds to the prefix plus
-- operator in programming languages.
--
-- Note that the result of this operation is affected by context and may
-- set flags.
plus :: (Precision p, Rounding r) => Decimal a b -> Arith p r (Decimal p r)
-- | minus takes one operand, and corresponds to the prefix minus
-- operator in programming languages.
--
-- Note that the result of this operation is affected by context and may
-- set flags. The copyNegate operation may be used instead
-- of minus if this is not desired.
minus :: (Precision p, Rounding r) => Decimal a b -> Arith p r (Decimal p r)
-- | abs takes one operand. If the operand is negative, the result
-- is the same as using the minus operation on the operand.
-- Otherwise, the result is the same as using the plus operation
-- on the operand.
--
-- Note that the result of this operation is affected by context and may
-- set flags. The copyAbs operation may be used if this is
-- not desired.
abs :: (Precision p, Rounding r) => Decimal a b -> Arith p r (Decimal p r)
-- | compare takes two operands and compares their values
-- numerically. If either operand is a special value then the
-- general rules apply. No flags are set unless an operand is a signaling
-- NaN.
--
-- Otherwise, the operands are compared, returning Right
-- LT if the first is less than the second, Right
-- EQ if they are equal, or Right GT
-- if the first is greater than the second.
--
-- A Left value is returned if the result is NaN, indicating an
-- “unordered” comparison (see IEEE 754 §5.11).
compare :: Decimal a b -> Decimal c d -> Arith p r (Either (Decimal p r) Ordering)
-- | compareSignal takes two operands and compares their values
-- numerically. This operation is identical to compare, except
-- that if neither operand is a signaling NaN then any quiet NaN operand
-- is treated as though it were a signaling NaN. (That is, all NaNs
-- signal, with signaling NaNs taking precedence over quiet NaNs.)
compareSignal :: Decimal a b -> Decimal c d -> Arith p r (Either (Decimal p r) Ordering)
-- | min takes two operands, compares their values numerically, and
-- returns the minimum. If either operand is a NaN then the general rules
-- apply, unless one is a quiet NaN and the other is numeric, in which
-- case the numeric operand is returned.
min :: Decimal a b -> Decimal a b -> Arith p r (Decimal a b)
-- | max takes two operands, compares their values numerically, and
-- returns the maximum. If either operand is a NaN then the general rules
-- apply, unless one is a quiet NaN and the other is numeric, in which
-- case the numeric operand is returned.
max :: Decimal a b -> Decimal a b -> Arith p r (Decimal a b)
-- | minMagnitude takes two operands and compares their values
-- numerically with their sign ignored and assumed to be 0.
--
-- If, without signs, the first operand is the smaller then the original
-- first operand is returned (that is, with the original sign). If,
-- without signs, the second operand is the smaller then the original
-- second operand is returned. Otherwise the result is the same as from
-- the min operation.
minMagnitude :: Decimal a b -> Decimal a b -> Arith p r (Decimal a b)
-- | maxMagnitude takes two operands and compares their values
-- numerically with their sign ignored and assumed to be 0.
--
-- If, without signs, the first operand is the larger then the original
-- first operand is returned (that is, with the original sign). If,
-- without signs, the second operand is the larger then the original
-- second operand is returned. Otherwise the result is the same as from
-- the max operation.
maxMagnitude :: Decimal a b -> Decimal a b -> Arith p r (Decimal a b)
-- | roundToIntegralValue takes one operand. It is identical to the
-- roundToIntegralExact operation except that the Inexact
-- and Rounded flags are never set even if the operand is rounded
-- (that is, the operation is quiet unless the operand is a signaling
-- NaN).
roundToIntegralValue :: (Precision a, Rounding r) => Decimal a b -> Arith p r (Decimal a r)
-- | roundToIntegralExact takes one operand. If the operand is a
-- special value, or the exponent of the operand is non-negative,
-- then the result is the same as the operand (unless the operand is a
-- signaling NaN, as usual).
--
-- Otherwise (the operand has a negative exponent) the result is the same
-- as using the quantize operation using the given operand as the
-- left-hand-operand, 1E+0 as the right-hand-operand, and the precision
-- of the operand as the precision setting. The rounding mode is
-- taken from the context, as usual.
roundToIntegralExact :: (Precision a, Rounding r) => Decimal a b -> Arith p r (Decimal a r)
-- | quantize takes two operands. If either operand is a special
-- value then the general rules apply, except that if either operand
-- is infinite and the other is finite an Invalid operation condition is
-- raised and the result is NaN, or if both are infinite then the result
-- is the first operand.
--
-- Otherwise (both operands are finite), quantize returns the
-- number which is equal in value (except for any rounding) and sign to
-- the first (left-hand) operand and which has an exponent set to
-- be equal to the exponent of the second (right-hand) operand.
--
-- The coefficient of the result is derived from that of the
-- left-hand operand. It may be rounded using the current rounding
-- setting (if the exponent is being increased), multiplied by a
-- positive power of ten (if the exponent is being decreased), or
-- is unchanged (if the exponent is already equal to that of the
-- right-hand operand).
--
-- Unlike other operations, if the length of the coefficient after
-- the quantize operation would be greater than precision then an
-- Invalid operation condition is raised. This guarantees that, unless
-- there is an error condition, the exponent of the result of a
-- quantize is always equal to that of the right-hand operand.
--
-- Also unlike other operations, quantize will never raise Underflow,
-- even if the result is subnormal and inexact.
quantize :: (Precision p, Rounding r) => Decimal a b -> Decimal c d -> Arith p r (Decimal p r)
-- | reduce takes one operand. It has the same semantics as the
-- plus operation, except that if the final result is finite it is
-- reduced to its simplest form, with all trailing zeros removed and its
-- sign preserved.
reduce :: (Precision p, Rounding r) => Decimal a b -> Arith p r (Decimal p r)
-- | and is a logical operation which takes two logical operands.
-- The result is the digit-wise and of the two operands; each
-- digit of the result is the logical and of the corresponding digits of
-- the operands, aligned at the least-significant digit. A result digit
-- is 1 if both of the corresponding operand digits are 1; otherwise it
-- is 0.
and :: Precision p => Decimal a b -> Decimal c d -> Arith p r (Decimal p r)
-- | or is a logical operation which takes two logical operands. The
-- result is the digit-wise inclusive or of the two operands; each
-- digit of the result is the logical or of the corresponding digits of
-- the operands, aligned at the least-significant digit. A result digit
-- is 1 if either or both of the corresponding operand digits is 1;
-- otherwise it is 0.
or :: Precision p => Decimal a b -> Decimal c d -> Arith p r (Decimal p r)
-- | xor is a logical operation which takes two logical operands.
-- The result is the digit-wise exclusive or of the two operands;
-- each digit of the result is the logical exclusive-or of the
-- corresponding digits of the operands, aligned at the least-significant
-- digit. A result digit is 1 if one of the corresponding operand digits
-- is 1 and the other is 0; otherwise it is 0.
xor :: Precision p => Decimal a b -> Decimal c d -> Arith p r (Decimal p r)
-- | invert is a logical operation which takes one logical operand.
-- The result is the digit-wise inversion of the operand; each
-- digit of the result is the inverse of the corresponding digit of the
-- operand. A result digit is 1 if the corresponding operand digit is 0;
-- otherwise it is 0.
invert :: FinitePrecision p => Decimal a b -> Arith p r (Decimal p r)
-- | shift takes two operands. The second operand must be an integer
-- (with an exponent of 0) in the range −precision through
-- precision. If the first operand is a NaN then the general
-- arithmetic rules apply, and if it is infinite then the result is the
-- Infinity unchanged.
--
-- Otherwise (the first operand is finite) the result has the same
-- sign and exponent as the first operand, and a
-- coefficient which is a shifted copy of the digits in the
-- coefficient of the first operand. The number of places to shift is
-- taken from the absolute value of the second operand, with the shift
-- being to the left if the second operand is positive or to the right
-- otherwise. Digits shifted into the coefficient are zeros.
--
-- The only flag that might be set is InvalidOperation (set
-- if the first operand is an sNaN or the second is not valid).
--
-- The rotate operation can be used to rotate rather than shift a
-- coefficient.
shift :: Precision p => Decimal a b -> Decimal c d -> Arith p r (Decimal p r)
-- | rotate takes two operands. The second operand must be an
-- integer (with an exponent of 0) in the range −precision
-- through precision. If the first operand is a NaN then the
-- general arithmetic rules apply, and if it is infinite then the result
-- is the Infinity unchanged.
--
-- Otherwise (the first operand is finite) the result has the same
-- sign and exponent as the first operand, and a
-- coefficient which is a rotated copy of the digits in the
-- coefficient of the first operand. The number of places of rotation is
-- taken from the absolute value of the second operand, with the rotation
-- being to the left if the second operand is positive or to the right
-- otherwise.
--
-- If the coefficient of the first operand has fewer than
-- precision digits, it is treated as though it were padded on the
-- left with zeros to length precision before the rotation.
-- Similarly, if the coefficient of the first operand has more than
-- precision digits, it is truncated on the left before use.
--
-- The only flag that might be set is InvalidOperation (set
-- if the first operand is an sNaN or the second is not valid).
--
-- The shift operation can be used to shift rather than rotate a
-- coefficient.
rotate :: FinitePrecision p => Decimal a b -> Decimal c d -> Arith p r (Decimal p r)
-- | isZero takes one operand. The result is True if the
-- operand is a zero; otherwise it is False. This operation is
-- unaffected by context and is quiet — no flags are changed in
-- the context.
isZero :: Decimal a b -> Arith p r Bool
-- | isSigned takes one operand. The result is True if the
-- sign of the operand is 1; otherwise it is False. This
-- operation is unaffected by context and is quiet — no flags are
-- changed in the context.
isSigned :: Decimal a b -> Arith p r Bool
-- | isFinite takes one operand. The result is True if the
-- operand is neither infinite nor a NaN (that is, it is a normal number,
-- a subnormal number, or a zero); otherwise it is False. This
-- operation is unaffected by context and is quiet — no flags are
-- changed in the context.
isFinite :: Decimal a b -> Arith p r Bool
-- | isInfinite takes one operand. The result is True if the
-- operand is an Infinity; otherwise it is False. This operation
-- is unaffected by context and is quiet — no flags are changed in
-- the context.
isInfinite :: Decimal a b -> Arith p r Bool
-- | isNormal takes one operand. The result is True if the
-- operand is a positive or negative normal number; otherwise it
-- is False. This operation is quiet; no flags are changed
-- in the context.
isNormal :: Precision a => Decimal a b -> Arith p r Bool
-- | isSubnormal takes one operand. The result is True if the
-- operand is a positive or negative subnormal number; otherwise
-- it is False. This operation is quiet; no flags are
-- changed in the context.
isSubnormal :: Precision a => Decimal a b -> Arith p r Bool
-- | isNaN takes one operand. The result is True if the
-- operand is a NaN (quiet or signaling); otherwise it is False.
-- This operation is unaffected by context and is quiet — no flags
-- are changed in the context.
isNaN :: Decimal a b -> Arith p r Bool
-- | isQNaN takes one operand. The result is True if the
-- operand is a quiet NaN; otherwise it is False. This operation
-- is unaffected by context and is quiet — no flags are changed in
-- the context.
isQNaN :: Decimal a b -> Arith p r Bool
-- | isSNaN takes one operand. The result is True if the
-- operand is a signaling NaN; otherwise it is False. This
-- operation is unaffected by context and is quiet — no flags are
-- changed in the context.
isSNaN :: Decimal a b -> Arith p r Bool
-- | isCanonical takes one operand. The result is True if the
-- operand is canonical; otherwise it is False. The
-- definition of canonical is implementation-defined; if more than
-- one internal encoding for a given NaN, Infinity, or finite number is
-- possible then one “preferred” encoding is deemed canonical. This
-- operation then tests whether the internal encoding is that preferred
-- encoding.
--
-- If all possible operands have just one internal encoding each, then
-- isCanonical always returns True. This operation is
-- unaffected by context and is quiet — no flags are changed in
-- the context.
isCanonical :: Decimal a b -> Arith p r Bool
-- | compareTotal takes two operands and compares them using their
-- abstract representation rather than their numerical value. A total
-- ordering is defined for all possible abstract representations, as
-- described below. If the first operand is lower in the total order than
-- the second operand then the result is LT, if the operands have
-- the same abstract representation then the result is EQ, and if
-- the first operand is higher in the total order than the second operand
-- then the result is GT. The total ordering is defined as
-- follows.
--
--
-- - The following items describe the ordering for representations
-- whose sign is 0. If the sign is 1, the order is
-- reversed. A representation with a sign of 1 is always lower in
-- the ordering than one with a sign of 0.
-- - Numbers (representations which are not NaNs) are ordered such that
-- a larger numerical value is higher in the ordering. If two
-- representations have the same numerical value then the exponent is
-- taken into account; larger (more positive) exponents are higher in the
-- ordering.
-- - All quiet NaNs are higher in the total ordering than all signaling
-- NaNs.
-- - Quiet NaNs and signaling NaNs are ordered according to their
-- payload; a larger payload is higher in the ordering.
--
--
-- For example, the following values are ordered from lowest to highest:
-- -NaN -sNaN -Infinity -127 -1 -1.00 -0 -0.000 0 1.2300 1.23 1E+9
-- Infinity sNaN NaN NaN456.
compareTotal :: Decimal a b -> Decimal c d -> Arith p r Ordering
-- | compareTotalMagnitude takes two operands and compares them
-- using their abstract representation rather than their numerical value
-- and with their sign ignored and assumed to be 0. The result is
-- identical to that obtained by using compareTotal on two
-- operands which are the copyAbs copies of the operands to
-- compareTotalMagnitude.
compareTotalMagnitude :: Decimal a b -> Decimal c d -> Arith p r Ordering
-- | class' takes one operand. The result is an indication of the
-- class of the operand, where the class is one of ten
-- possibilities, corresponding to one of the strings "sNaN"
-- (signaling NaN), "NaN" (quiet NaN), "-Infinity"
-- (negative infinity), "-Normal" (negative normal finite
-- number), "-Subnormal" (negative subnormal finite number),
-- "-Zero" (negative zero), "+Zero" (non-negative
-- zero), "+Subnormal" (positive subnormal finite number),
-- "+Normal" (positive normal finite number), or
-- "+Infinity" (positive infinity). This operation is quiet; no
-- flags are changed in the context.
--
-- Note that unlike the special values in the model, the sign of any NaN
-- is ignored in the classification, as required by IEEE 754.
class' :: Precision a => Decimal a b -> Arith p r Class
data Class
-- | Number (finite or infinite)
NumberClass :: Sign -> NumberClass -> Class
-- | Not a number (quiet or signaling)
NaNClass :: NaNClass -> Class
data Sign
-- | Positive or non-negative
Pos :: Sign
-- | Negative
Neg :: Sign
data NumberClass
-- | Zero
ZeroClass :: NumberClass
-- | Subnormal finite number
SubnormalClass :: NumberClass
-- | Normal finite number
NormalClass :: NumberClass
-- | Infinity
InfinityClass :: NumberClass
data NaNClass
-- | Quiet NaN
QuietClass :: NaNClass
-- | Signaling NaN
SignalingClass :: NaNClass
-- | logb takes one operand. If the operand is a NaN then the
-- general arithmetic rules apply. If the operand is infinite then
-- +Infinity is returned. If the operand is a zero, then −Infinity is
-- returned and the Division by zero exceptional condition is raised.
--
-- Otherwise, the result is the integer which is the exponent of the
-- magnitude of the most significant digit of the operand (as though the
-- operand were truncated to a single digit while maintaining the value
-- of that digit and without limiting the resulting exponent). All
-- results are exact unless an integer result does not fit in the
-- available precision.
logb :: (Precision p, Rounding r) => Decimal a b -> Arith p r (Decimal p r)
-- | scaleb takes two operands. If either operand is a NaN then the
-- general arithmetic rules apply. Otherwise, the second operand must be
-- a finite integer with an exponent of zero and in the range ±2 ×
-- (Emax + precision) inclusive, where Emax is the
-- largest value that can be returned by the logb operation at the
-- same precision setting. (If is is not, the Invalid Operation
-- condition is raised and the result is NaN.)
--
-- If the first operand is infinite then that Infinity is returned,
-- otherwise the result is the first operand modified by adding the value
-- of the second operand to its exponent. The result may Overflow
-- or Underflow.
scaleb :: Decimal a b -> Decimal c d -> Arith p r (Decimal a b)
-- | sameQuantum takes two operands, and returns True if the
-- two operands have the same exponent or False otherwise.
-- The result is never affected by either the sign or the coefficient of
-- either operand.
--
-- If either operand is a special value, True is returned
-- only if both operands are NaNs or both are infinities.
--
-- sameQuantum does not change any flags in the context.
sameQuantum :: Decimal a b -> Decimal c d -> Arith p r Bool
-- | radix takes no operands. The result is the radix (base) in
-- which arithmetic is effected; for this specification the result will
-- have the value 10.
radix :: Precision p => Arith p r (Decimal p r)
-- | copyAbs takes one operand. The result is a copy of the operand
-- with the sign set to 0. Unlike the abs operation, this
-- operation is unaffected by context and is quiet — no flags are
-- changed in the context.
copyAbs :: Decimal a b -> Arith p r (Decimal a b)
-- | copyNegate takes one operand. The result is a copy of the
-- operand with the sign inverted (a sign of 0 becomes 1
-- and vice versa). Unlike the minus operation, this operation is
-- unaffected by context and is quiet — no flags are changed in
-- the context.
copyNegate :: Decimal a b -> Arith p r (Decimal a b)
-- | copySign takes two operands. The result is a copy of the first
-- operand with the sign set to be the same as the sign of
-- the second operand. This operation is unaffected by context and is
-- quiet — no flags are changed in the context.
copySign :: Decimal a b -> Decimal c d -> Arith p r (Decimal a b)
-- | copy takes one operand. The result is a copy of the operand.
-- This operation is unaffected by context and is quiet — no flags
-- are changed in the context.
copy :: Decimal a b -> Arith p r (Decimal a b)
-- | canonical takes one operand. The result has the same value as
-- the operand but always uses a canonical encoding. The
-- definition of canonical is implementation-defined; if more than
-- one internal encoding for a given NaN, Infinity, or finite number is
-- possible then one “preferred” encoding is deemed canonical. This
-- operation then returns the value using that preferred encoding.
--
-- If all possible operands have just one internal encoding each, then
-- canonical always returns the operand unchanged (that is, it has
-- the same effect as copy). This operation is unaffected by
-- context and is quiet — no flags are changed in the context.
canonical :: Decimal a b -> Arith p r (Decimal a b)
instance GHC.Classes.Eq Numeric.Decimal.Operation.Class
instance GHC.Enum.Enum Numeric.Decimal.Operation.NaNClass
instance GHC.Classes.Eq Numeric.Decimal.Operation.NaNClass
instance GHC.Classes.Eq Numeric.Decimal.Operation.NumberClass
instance GHC.Show.Show Numeric.Decimal.Operation.Class
-- | This module provides a general-purpose number type supporting decimal
-- arithmetic for both limited precision floating-point (IEEE 754-2008)
-- and for arbitrary precision floating-point (following the same
-- principles as IEEE 754 and IEEE 854-1987) as described in the
-- General Decimal Arithmetic Specification by Mike Cowlishaw. In
-- addition to floating-point arithmetic, integer and unrounded
-- floating-point arithmetic are included as subsets.
--
-- Unlike the binary floating-point types Float and Double,
-- decimal number types can perform decimal arithmetic exactly.
-- Internally, decimal numbers are represented with an integral
-- coefficient and base-10 exponent.
--
--
-- >>> 29.99 + 4.71 :: Double
-- 34.699999999999996
--
--
--
-- >>> 29.99 + 4.71 :: BasicDecimal
-- 34.70
--
--
--
-- >>> 0.1 + 0.2 == (0.3 :: Double)
-- False
--
--
--
-- >>> 0.1 + 0.2 == (0.3 :: BasicDecimal)
-- True
--
--
-- Decimal numbers support lossless conversion to and from a string
-- representation via Show and Read instances. Note that
-- there may be multiple representations of values that are numerically
-- equal (e.g. 1 and 1.00) which are preserved by this conversion.
--
-- Some decimal numbers also support encoding and decoding specific IEEE
-- 754 interchange formats via a Binary instance.
module Numeric.Decimal
-- | A decimal floating point number with selectable precision and rounding
-- algorithm
data Decimal p r
-- | A decimal floating point number with 9 digits of precision, rounding
-- half up
type BasicDecimal = Decimal P9 RoundHalfUp
-- | A decimal floating point number with selectable precision, rounding
-- half even
type ExtendedDecimal p = Decimal p RoundHalfEven
-- | A decimal floating point number with infinite precision
type GeneralDecimal = ExtendedDecimal PInfinite
-- | A decimal floating point number with 7 digits of precision, rounding
-- half even, and a 32-bit encoded representation using the
-- decimal32 interchange format (with a decimal encoding for the
-- coefficient)
type Decimal32 = ExtendedDecimal Pdecimal32
-- | A decimal floating point number with 16 digits of precision, rounding
-- half even, and a 64-bit encoded representation using the
-- decimal64 interchange format (with a decimal encoding for the
-- coefficient)
type Decimal64 = ExtendedDecimal Pdecimal64
-- | A decimal floating point number with 34 digits of precision, rounding
-- half even, and a 128-bit encoded representation using the
-- decimal128 interchange format (with a decimal encoding for the
-- coefficient)
type Decimal128 = ExtendedDecimal Pdecimal128
-- | Precision indicates the maximum number of significant decimal digits a
-- number may have.
class Precision p where eMax n = subtract 1 . (10 ^) . numDigits <$> base where mlength = precision n :: Maybe Int base = (10 *) . fromIntegral <$> mlength :: Maybe Coefficient eMin = fmap (1 -) . eMax
-- | A subclass of precisions that are finite
class Precision p => FinitePrecision p
-- | A precision of 1 significant digit
data P1
-- | A precision of 2 significant digits
type P2 = PTimes2 P1
-- | A precision of 3 significant digits
type P3 = PPlus1 P2
-- | Et cetera
type P4 = PTimes2 P2
type P5 = PPlus1 P4
type P6 = PTimes2 P3
type P7 = PPlus1 P6
type P8 = PTimes2 P4
type P9 = PPlus1 P8
type P10 = PTimes2 P5
type P11 = PPlus1 P10
type P12 = PTimes2 P6
type P13 = PPlus1 P12
type P14 = PTimes2 P7
type P15 = PPlus1 P14
type P16 = PTimes2 P8
type P17 = PPlus1 P16
type P18 = PTimes2 P9
type P19 = PPlus1 P18
type P20 = PTimes2 P10
type P21 = PPlus1 P20
type P22 = PTimes2 P11
type P23 = PPlus1 P22
type P24 = PTimes2 P12
type P25 = PPlus1 P24
type P26 = PTimes2 P13
type P27 = PPlus1 P26
type P28 = PTimes2 P14
type P29 = PPlus1 P28
type P30 = PTimes2 P15
type P31 = PPlus1 P30
type P32 = PTimes2 P16
type P33 = PPlus1 P32
type P34 = PTimes2 P17
type P35 = PPlus1 P34
type P36 = PTimes2 P18
type P37 = PPlus1 P36
type P38 = PTimes2 P19
type P39 = PPlus1 P38
type P40 = PTimes2 P20
type P41 = PPlus1 P40
type P42 = PTimes2 P21
type P43 = PPlus1 P42
type P44 = PTimes2 P22
type P45 = PPlus1 P44
type P46 = PTimes2 P23
type P47 = PPlus1 P46
type P48 = PTimes2 P24
type P49 = PPlus1 P48
type P50 = PTimes2 P25
type P75 = PPlus1 P74
type P100 = PTimes2 P50
type P150 = PTimes2 P75
type P200 = PTimes2 P100
type P250 = PTimes2 P125
type P300 = PTimes2 P150
type P400 = PTimes2 P200
type P500 = PTimes2 P250
type P1000 = PTimes2 P500
type P2000 = PTimes2 P1000
-- | A precision of (p + 1) significant digits
data PPlus1 p
-- | A precision of (p × 2) significant digits
data PTimes2 p
-- | A precision of unlimited significant digits
data PInfinite
-- | A type with Precision instance specifying decimal32
-- interchange format parameters (using a decimal encoding for the
-- coefficient) having an effective precision of 7 decimal digits
type Pdecimal32 = Format K32 DecimalCoefficient
-- | A type with Precision instance specifying decimal64
-- interchange format parameters (using a decimal encoding for the
-- coefficient) having an effective precision of 16 decimal digits
type Pdecimal64 = Format K64 DecimalCoefficient
-- | A type with Precision instance specifying decimal128
-- interchange format parameters (using a decimal encoding for the
-- coefficient) having an effective precision of 34 decimal digits
type Pdecimal128 = Format K128 DecimalCoefficient
-- | A rounding algorithm to use when the result of an arithmetic operation
-- exceeds the precision of the result type
class Rounding r
-- | If the discarded digits represent greater than or equal to half (0.5)
-- of the value of a one in the next left position then the result
-- coefficient should be incremented by 1 (rounded up). Otherwise the
-- discarded digits are ignored.
data RoundHalfUp
-- | If the discarded digits represent greater than half (0.5) the value of
-- a one in the next left position then the result coefficient should be
-- incremented by 1 (rounded up). If they represent less than half, then
-- the result coefficient is not adjusted (that is, the discarded digits
-- are ignored).
--
-- Otherwise (they represent exactly half) the result coefficient is
-- unaltered if its rightmost digit is even, or incremented by 1 (rounded
-- up) if its rightmost digit is odd (to make an even digit).
data RoundHalfEven
-- | If the discarded digits represent greater than half (0.5) of the value
-- of a one in the next left position then the result coefficient should
-- be incremented by 1 (rounded up). Otherwise (the discarded digits are
-- 0.5 or less) the discarded digits are ignored.
data RoundHalfDown
-- | (Round toward +∞.) If all of the discarded digits are zero or if the
-- sign is 1 the result is unchanged. Otherwise, the result
-- coefficient should be incremented by 1 (rounded up).
data RoundCeiling
-- | (Round toward −∞.) If all of the discarded digits are zero or if the
-- sign is 0 the result is unchanged. Otherwise, the sign is 1 and
-- the result coefficient should be incremented by 1.
data RoundFloor
-- | (Round away from 0.) If all of the discarded digits are zero the
-- result is unchanged. Otherwise, the result coefficient should be
-- incremented by 1 (rounded up).
data RoundUp
-- | (Round zero or five away from 0.) The same as RoundUp, except
-- that rounding up only occurs if the digit to be rounded up is 0 or 5,
-- and after overflow the result is the same as for RoundDown.
data Round05Up
-- | (Round toward 0; truncate.) The discarded digits are ignored; the
-- result is unchanged.
data RoundDown
-- | Cast a Decimal to another precision and/or rounding algorithm,
-- immediately rounding if necessary to the new precision using the new
-- algorithm.
cast :: (Precision p, Rounding r) => Decimal a b -> Decimal p r
-- | Return 0 or 1 if the argument is False or
-- True, respectively. This is basically an optimized
-- toEnum . fromEnum and allows an all-decimal
-- usage of the operations from Numeric.Decimal.Operation that
-- return a Bool.
fromBool :: Bool -> Decimal p r
-- | Return -1, 0, or 1 if the argument is
-- LT, EQ, or GT, respectively. This allows an
-- all-decimal usage of the operations from
-- Numeric.Decimal.Operation that return an Ordering.
fromOrdering :: Ordering -> Decimal p r