deka-0.1.0.0: Decimal floating point arithmetic

Safe HaskellSafe

Data.Deka.IO

Contents

Description

Floating-point decimals.

This uses the decNumber C library, so you will want to read the documentation about it to fully understand this module:

http://speleotrove.com/decimal/decnumber.html

http://speleotrove.com/decimal/decarith.html

http://speleotrove.com/decimal/

In particular, this module implements the decQuad type. decQuad supports up to 34 digits of precision and exponents up to (roughly) 6144. It doesn't silently round, overflow, or underflow; rather, the library will notify you if these things happen.

Every function in this module returns canonical Quad (contrast the decNumber library which will, under limited circumstances, return non-canonical decimals). I am not certain that canonical vs. non-canonical matters in typical use, though it may matter when using compareTotal.

Many functions in this module clash with Prelude names, so you might want to do

 import qualified Data.Deka.Pure as D

Synopsis

Quad

data Quad Source

Decimal number. This is immutable, like any Haskell value you would ordinarily work with. (Actually, that is a bit of a lie. Under the covers it is a pointer to a C struct, which is in fact mutable like anything in C. However, no function exposed in this API mutates a Quad's pointee after the Quad is created.)

As indicated in the General Decimal Arithmetic specification, a Quad might be a finite number (perhaps the most common type) or it might be infinite or a not-a-number. decClass will tell you a little more about a particular Quad.

Rounding

For more on the rounding algorithms, see

http://speleotrove.com/decimal/damodel.html

data Round Source

Instances

Flags

For more on possible flags, see

http://speleotrove.com/decimal/damodel.html

data Flag Source

Instances

data Flags Source

A container for multiple Flag indicating which are set and which are not.

Instances

checkFlag :: Flag -> Flags -> BoolSource

Is this Flag set?

emptyFlags :: FlagsSource

A Flags with no Flag set.

flagList :: Flags -> [String]Source

Gives a list of strings, one for each flag that is set.

Env monad

data Env a Source

The Env monad

Since Deka is a binding to a C library, all the work happens in the mutable land of C pointers. That means that everything happens in the IO monad. The Env monad is simply a wrapper of the IO monad. Since the Env data constructor is not exported, you can't do arbitrary IO computations in the monad; you can only do the computations from this module. Because all the computations in this module do not create observable side effects, it is safe to use unsafePerformIO to perform Env computations in a pure function. This module does not have such a function so that this module can stay Safe for Safe Haskell purposes; however, the Data.Deka.Pure module does have such a function.

Ctx monad

data Ctx a Source

The Ctx monad

The General Decimal Arithmetic specification states that most computations occur within a context, which affects the manner in which computations are done (for instance, the context determines the rounding algorithm). The context also carries some results from computations (for instance, a computation might set a flag to indicate that the result is rounded or inexact or was a division by zero.) The Ctx monad carries this context.

Conceptually the Ctx monad includes the Env monad. Any Env computation can be lifted into a Ctx computation with a liftEnv. You will do most computations in the Ctx monad; however, on occasion it is useful to do computations entirely in the Env monad. You know that computations entirely in the Env monad are unaffected by, and cannot affect, the context.

The Ctx monad captures both the context and the IO. Because Quad is exposed only as an immutable type, and because there is no way to do arbitrary IO in the Ctx monad (which is why it is not an instance of the MonadIO class), it is safe to put an unsafePerformIO on Ctx computations so they can be done in pure functions.

getStatus :: Ctx FlagsSource

The current status flags, which indicate results from previous computations.

setStatus :: Flags -> Ctx ()Source

Set the current status to whatever you wish.

getRound :: Ctx RoundSource

The current rounding method

setRound :: Round -> Ctx ()Source

Change the current rounding method

runCtxIO :: Ctx a -> IO (a, Flags)Source

By default, rounding is half even. No status flags are set initially. Returns the final status flags along with the result of the computation.

liftEnv :: Env a -> Ctx aSource

Lifts an Env computation into a Ctx.

Class

data DecClass Source

Different categories of Quad.

decClass :: Quad -> Env DecClassSource

More information about a particular Quad.

Conversions

Digits

data Digit Source

A single decimal digit.

Constructors

D0 
D1 
D2 
D3 
D4 
D5 
D6 
D7 
D8 
D9 

digitsToIntegral :: [Digit] -> IntegerSource

The most significant digit is at the head of the list.

integralToDigits :: Integral a => a -> [Digit]Source

The most significant digit is at the head of the list. Sign of number is not relevant.

Complete encoding and decoding

Coefficients

data Coefficient Source

A list of digits, less than or equal to coefficientLen long. Corresponds only to finite numbers.

data Payload Source

A list of digits, less than or equal to payloadDigitsLen long.

Exponents

data Exponent Source

The signed integer which indicates the power of ten by which the coefficient is multiplied.

minMaxExp :: Coefficient -> (Exponent, Exponent)Source

The minimum and maximum possible exponent. If the coefficient has c digits, and Emax is x, the exponent e is within the closed-ended range

-x - (c - 1) + 1 and x - (c - 1)

See Decimal Arithmetic Specification version 1.70, page 10.

data AdjustedExp Source

An adjusted exponent is the value of an exponent of a number when that number is expressed as though in scientific notation with one digit before any decimal point. This is the finite exponent + (number of significant digits - 1).

minNormal :: AdjustedExpSource

The smallest possible adjusted exponent that is still normal. Adjusted exponents smaller than this are subnormal.

minNormalExp :: Coefficient -> ExponentSource

Like minNormal, but returns the size of the regular exponent rather than the adjusted exponent.

data CoeffExp Source

For a particular coefficient, the exponent must be in a particular range; coeffExp ensures this relationship is enforced.

coeffExp :: Coefficient -> Int -> Either String CoeffExpSource

Ensures the exponent falls within the correct range.

Sign, NaN, Value, Decoded

data Sign Source

Constructors

Sign0

The number is positive or is zero

Sign1

The number is negative or the negative zero

data NaN Source

Constructors

Quiet 
Signaling 

Instances

data Decoded Source

Constructors

Decoded 

Fields

dSign :: Sign
 
dValue :: Value
 

fromBCD :: Decoded -> Env QuadSource

Encodes a new Quad. The result is always canonical. However, the function does not signal if the result is an sNaN.

Strings

fromByteString :: ByteString -> Ctx QuadSource

Reads a ByteString, which can be in scientific, engineering, or "regular" decimal notation. Also reads NaN, Infinity, etc. Will return a signaling NaN and set the Invalid flag if the string given is invalid.

In the decNumber C library, this function was called fromString; the name was changed here because it doesn't take a regular Haskell String.

toByteString :: Quad -> Env ByteStringSource

Converts a Quad to a string. May use non-scientific notation, but only if that's unambiguous; otherwise, uses scientific notation.

In the decNumber C library, this is called toString; the name was changed here because this function doesn't return a Haskell String.

toEngByteString :: Quad -> Env ByteStringSource

Returns a string in engineering notation.

In the decNumber C library, this is called toEngString; the name is changed here because the function does not return a regular Haskell String.

Integers

Other Quad

Arithmetic

fma :: Quad -> Quad -> Quad -> Ctx QuadSource

fused multiply add.

Exponent and coefficient adjustment

quantize :: Quad -> Quad -> Ctx QuadSource

quantize x y returns z which is x set to have the same quantum as y; that is, numerically the same value but rounded or padded if necessary to have the same exponent as y. Useful for rounding monetary quantities.

Comparisons

compare :: Quad -> Quad -> Ctx QuadSource

Compares two Quad numerically. The result might be -1, 0, 1, or NaN, where -1 means x is less than y, 0 indicates numerical equality, 1 means y is greater than x. NaN is returned only if x or y is an NaN.

Thus, this function does not return an Ordering because the result might be an NaN.

compareSignal :: Quad -> Quad -> Ctx QuadSource

Same as compare, but a quietNaN is treated like a signaling NaN (sets invalidOperation).

compareTotal :: Quad -> Quad -> Env QuadSource

Compares using an IEEE 754 total ordering, which takes into account the exponent. IEEE 754 says that this function might return different results depending upon whether the operands are canonical; Quad are always canonical so you don't need to worry about that here.

compareTotalMag :: Quad -> Quad -> Env QuadSource

Same as compareTotal but compares the absolute value of the two arguments.

Tests

isInteger :: Quad -> Env BoolSource

True if x is finite and has exponent of 0; False otherwise. This can lead to unexpected results; for instance, 3 x 10 ^ 2 is 300, but this function will return False.

isLogical :: Quad -> Env BoolSource

True only if x is zero or positive, an integer (finite with exponent of 0), and the coefficient is only zeroes and/or ones.

isNegative :: Quad -> Env BoolSource

True only if x is less than zero and is not an NaN.

isNormal :: Quad -> Env BoolSource

True only if x is finite, non-zero, and not subnormal.

isPositive :: Quad -> Env BoolSource

True only if x is greater than zero and is not an NaN.

isSignaling :: Quad -> Env BoolSource

True only if x is a signaling NaN.

isSigned :: Quad -> Env BoolSource

True only if x has a sign of 1. Note that zeroes and NaNs may have sign of 1.

isSubnormal :: Quad -> Env BoolSource

True only if x is subnormal - that is, finite, non-zero, and with a magnitude less than 10 ^ emin.

isZero :: Quad -> Env BoolSource

True only if x is a zero.

Signs

plus :: Quad -> Ctx QuadSource

Same effect as 0 + x where the exponent of the zero is the same as that of x if x is finite). NaNs are handled as for arithmetic operations.

abs :: Quad -> Ctx QuadSource

Absolute value. NaNs are handled normally (the sign of an NaN is not affected, and an sNaN sets invalidOperation.

copySign :: Quad -> Quad -> Env QuadSource

copySign x y returns z, which is a copy of x but has the sign of y. Unlike decQuadCopySign, the result is always canonical. This function never raises any signals.

Increment and decrement

Logical, bitwise, digit shifting

and :: Quad -> Quad -> Ctx QuadSource

Digit-wise logical and. Operands must be:

  • zero or positive * integers * comprise only zeroes and/or ones

If not, invalidOperation is set.

or :: Quad -> Quad -> Ctx QuadSource

Digit wise logical inclusive Or. Operands must be:

  • zero or positive * integers * comprise only zeroes and/or ones

If not, invalidOperation is set.

Transcendental

Attributes

Constants

Library info

Decoded predicates

These duplicate the tests that are available in the Env monad.

dIsLogical :: Decoded -> BoolSource

True only if x is zero or positive, an integer (finite with exponent of 0), and the coefficient is only zeroes and/or ones. The sign must be Sign0 (that is, you cannot have a negative zero.)

dIsNegative :: Decoded -> BoolSource

True only if x is less than zero and is not an NaN. It's not enough for the sign to be Sign1; the coefficient (if finite) must be greater than zero.

dIsZero :: Decoded -> BoolSource

True for any zero (negative or positive zero).

dDigits :: Coefficient -> IntSource

The number of significant digits. Zero returns 1.