-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Decimal numbers with variable precision
--   
--   A decimal number has an integer mantissa and a negative exponent. The
--   exponent can be interpreted as the number of decimal places in the
--   value.
@package Decimal
@version 0.4.2


-- | Decimal numbers are represented as <tt>m*10^(-e)</tt> where <tt>m</tt>
--   and <tt>e</tt> are integers. The exponent <tt>e</tt> is an unsigned
--   Word8. Hence the smallest value that can be represented is
--   <tt>10^-255</tt>.
--   
--   Unary arithmetic results have the exponent of the argument. Addition
--   and subtraction results have an exponent equal to the maximum of the
--   exponents of the arguments. Other operators have exponents sufficient
--   to show the exact result, up to a limit of 255:
--   
--   <pre>
--   0.15 * 0.15 :: Decimal    = 0.0225
--   (1/3) :: Decimal          = 0.33333333333333...
--   decimalPlaces (1/3)       = 255
--   </pre>
--   
--   While <tt>(/)</tt> is defined, you don't normally want to use it.
--   Instead The functions "divide" and "allocate" will split a decimal
--   amount into lists of results which are guaranteed to sum to the
--   original number. This is a useful property when doing financial
--   arithmetic.
--   
--   The arithmetic on mantissas is always done using <tt>Integer</tt>,
--   regardless of the type of <tt>DecimalRaw</tt> being manipulated. In
--   practice it is strongly recommended that <tt>Decimal</tt> be used,
--   with other types being used only where necessary (e.g. to conform to a
--   network protocol). For instance <tt>(1/3) :: DecimalRaw Int</tt> does
--   not give the right answer.
module Data.Decimal

-- | Raw decimal arithmetic type constructor. A decimal value consists of
--   an integer mantissa and a negative exponent which is interpreted as
--   the number of decimal places. The value stored in a <tt>Decimal d</tt>
--   is therefore equal to:
--   
--   <pre>
--   decimalMantissa d / (10 ^ decimalPlaces d)
--   </pre>
--   
--   The <a>Show</a> instance will add trailing zeros, so <tt>show $
--   Decimal 3 1500</tt> will return "1.500". Conversely the <a>Read</a>
--   instance will use the decimal places to determine the precision.
--   
--   Regardless of the type of the arguments, all mantissa arithmetic is
--   done using <tt>Integer</tt> types, so application developers do not
--   need to worry about overflow in the internal algorithms. However the
--   result of each operator will be converted to the mantissa type without
--   checking for overflow.
data DecimalRaw i
Decimal :: !Word8 -> !i -> DecimalRaw i
[decimalPlaces] :: DecimalRaw i -> !Word8
[decimalMantissa] :: DecimalRaw i -> !i

-- | Arbitrary precision decimal type. Programs should do decimal
--   arithmetic with this type and only convert to other instances of
--   <a>DecimalRaw</a> where required by an external interface.
--   
--   Using this type is also faster because it avoids repeated conversions
--   to and from <tt>Integer</tt>.
type Decimal = DecimalRaw Integer

-- | Convert a real fractional value into a Decimal of the appropriate
--   precision.
realFracToDecimal :: (Integral i, RealFrac r) => Word8 -> r -> DecimalRaw i

-- | Convert a <tt>DecimalRaw</tt> from one base to another. Returns
--   <tt>Nothing</tt> if this would cause arithmetic overflow.
decimalConvert :: (Integral a, Integral b, Bounded b) => DecimalRaw a -> Maybe (DecimalRaw b)

-- | Convert a <tt>DecimalRaw</tt> from one base representation to another.
--   Does not check for overflow in the new representation. Only use after
--   using "roundTo" to put an upper value on the exponent, or to convert
--   to a larger representation.
unsafeDecimalConvert :: (Integral a, Integral b) => DecimalRaw a -> DecimalRaw b

-- | Round a <tt>DecimalRaw</tt> to a specified number of decimal places.
--   If the value ends in <tt>5</tt> then it is rounded away from zero.
roundTo :: (Integral i) => Word8 -> DecimalRaw i -> DecimalRaw i

-- | Multiply a <tt>DecimalRaw</tt> by a <tt>RealFrac</tt> value.
(*.) :: (Integral i, RealFrac r) => DecimalRaw i -> r -> DecimalRaw i

-- | Divide a <tt>DecimalRaw</tt> value into one or more portions. The
--   portions will be approximately equal, and the sum of the portions is
--   guaranteed to be the original value.
--   
--   The portions are represented as a list of pairs. The first part of
--   each pair is the number of portions, and the second part is the
--   portion value. Hence 10 dollars divided 3 ways will produce <tt>[(2,
--   3.33), (1, 3.34)]</tt>.
divide :: Decimal -> Int -> [(Int, Decimal)]

-- | Allocate a <tt>DecimalRaw</tt> value proportionately with the values
--   in a list. The allocated portions are guaranteed to add up to the
--   original value.
--   
--   Some of the allocations may be zero or negative, but the sum of the
--   list must not be zero. The allocation is intended to be as close as
--   possible to the following:
--   
--   <pre>
--   let result = allocate d parts
--   in all (== d / sum parts) $ zipWith (/) result parts
--   </pre>
allocate :: Decimal -> [Integer] -> [Decimal]

-- | Try to convert Rational to Decimal with absolute precision return
--   string with fail description if not converted
eitherFromRational :: (Integral i) => Rational -> Either String (DecimalRaw i)

-- | Reduce the exponent of the decimal number to the minimal possible
--   value
normalizeDecimal :: (Integral i) => DecimalRaw i -> DecimalRaw i
instance Control.DeepSeq.NFData i => Control.DeepSeq.NFData (Data.Decimal.DecimalRaw i)
instance GHC.Real.Integral i => GHC.Enum.Enum (Data.Decimal.DecimalRaw i)
instance (GHC.Real.Integral i, GHC.Show.Show i) => GHC.Show.Show (Data.Decimal.DecimalRaw i)
instance (GHC.Real.Integral i, GHC.Read.Read i) => GHC.Read.Read (Data.Decimal.DecimalRaw i)
instance GHC.Real.Integral i => GHC.Classes.Eq (Data.Decimal.DecimalRaw i)
instance GHC.Real.Integral i => GHC.Classes.Ord (Data.Decimal.DecimalRaw i)
instance GHC.Real.Integral i => GHC.Num.Num (Data.Decimal.DecimalRaw i)
instance GHC.Real.Integral i => GHC.Real.Real (Data.Decimal.DecimalRaw i)
instance GHC.Real.Integral i => GHC.Real.Fractional (Data.Decimal.DecimalRaw i)
instance GHC.Real.Integral i => GHC.Real.RealFrac (Data.Decimal.DecimalRaw i)
