Module Data.Dec64

support for Decimal numbers

Imports

Table of Content

Definitions

divu10LongLong

unsigned division by 10, using only 8 additions and 10 bit shifts

remu10LongLong

unsigned modulus 10, using only multiplication, addition and bit shifts

mulu10LongLong

multiplication by 10, with shift and add

this will be inlined, so only use strict variables as argument

data Positive = pure native long

We will do the real work with positive Decimals only and afterwards negate the result if need be

This will reduce the cases to be considered and ease overflow detection

Member Functions

coefficientPositiveLong

extract the coefficient from a Positive

This is simply an unsigned right shift by 8

exponentPositiveInt

extract the exponent, sign extended in an Int

fromBitsLongPositive
pure native (long)

Interpret the bits of the Long value as a Positive This is a no-operation, as Positives are Longs and every Long value is a valid Positive (though it might not be a number, see also Positive.nan).

isNaNPositiveBool

tell if a Positive is not a number. This works for all 2^56 NaN values.

isZeroPositiveBool

tell if a Positive is 0. This works for all 255 0 values.

maxCoefficientLong
pure native 72057594037927935L

the largest possible coefficient is 72_057_594_037_927_935

maxExponentInt
pure native 127

the largest exponent is 127

minCoefficientLong
pure native 0L

the smalles possible coefficient is 0

minExponentInt
pure native 0xffffff81

the smallest exponent is -127

nanPositive
pure native 0xDeadBeef80L

The canonical not a number value.

Note that there are 2^56 NaN values, all comparing equal.

onePositive
pure native 0x100L

The canonical Positive 1

packLongIntPositive

construct a Positive from a coefficient and an exponent

This will be Positive.nan if the coefficient is not in the range minCoefficient .. maxCoefficient or the exponent is not in the range minExponent .. maxExponent, even if the value could be represented. Thus:

 Positive.pack 72057594037927935 0     == 72057594037927935z
 Positive.pack 720575940379279350 (-1) == nan
toBitsPositiveLong
pure native (long)

Interpret the bits of a Positive as Long value. The result will look like this

 mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm eeee eeee
         54        48        40        32        24        16        8 7        0
  • The 8 e bits 0..7 are the exponent in 2's complement encoding
  • The 56 m bits 8..63 are the unsigned coefficient.
  • an exponent of -128 (0x80) signals not-a-number (NaN)
  • the value of a number that is not NaN is coefficient*(exp^10)

Note that there are usually several encodings for one and the same value. 1, for example, could be 0x100 or 0xAFF (10E-1) Likewise 5 could be represented as 5e0, 50e-1, 0.5e1 and so forth.

This is a no-operation, as Positives are Longs. However, the Frege compiler sees them as totally unrelated types (and rightly so).

zeroPositive
pure native 0L

The canonical Positive 0

expansionMaxLong
pure native 922337203685477580L

a coeficient cannot be multiplied by 10 if it is greater than 922337203685477_580

coeffExpansionMaxLong
pure native 7205759403792793L

a number greater than this, multiplied by 10, wouldn't fit anymore in the 56 coefficient bits

positiveDecimalPositive

get the absolute value of a Decimal as Positive

decimalIntPositiveDecimal

convert a Positive back to a Decimal with the sign indicated by the first argument

normRightPositivePositive

find the representation of a Positive with the smallest coefficient

NaN and 0 come out in their canonical forms

normLeftPositivePositive

find the representation of a Positive with the greatest coefficient

NaN and 0 come out in their canonical forms

normLeftDecimalDecimalDecimal

represent a Decimal with the greatest valid coefficient

NaN and 0 come out in their canonical forms

normLeftPositivePositivePositive

represent a Positive with the greatest valid coefficient

NaN and 0 come out in their canonical forms

ulpPPositivePositive
ulpDecimalDecimal

find the smallest number that makes a difference when adding it to the given number

nextUpDecimalDecimal

given a Decimal x find a Decimal y such that there is no Decimal z with x < z < y

nextDownDecimalDecimal

given a Decimal x find a Decimal y such that there is no Decimal z with x > z > y

comparePPositivePositiveOrdering
compareDDecimalDecimalOrdering
sigDigitsPositiveInt

tell the number of significant digits

packResultLongIntPositive

Pack an arithmetic result by dividing the coefficient by 10 until it fits.

This will loose precision if the coefficient came out larger than 56 bits.

addPPositivePositivePositive

add 2 Positive numbers

both numbers must not be NaN

diffPPositivePositivePositive

difference between 2 Positive numbers, where the first one must be >= the second one

both numbers must not be NaN

leadingZeroesLongInt
pure native java.lang.Long.numberOfLeadingZeros
relevantBitsLongInt
mulPPositivePositivePositive
recipPPositivePositive
twoPPositive
recipCheck ∷ (Enum α, Integral α) ⇒ α → α → [(α, Decimal, Decimal)]
reciprocalDecimalDecimal

Instances

instance Num Decimal

Member Functions

*DecimalDecimalDecimal
infixl  14
+DecimalDecimalDecimal
infixl  13
-DecimalDecimalDecimal
infixl  13
absDecimalDecimal

inherited from Num.abs

fromIntIntDecimal
fromIntegerIntegerDecimal
isInfiniteDecimalBool

inherited from Num.isInfinite

isNaNDecimalBool

tell if a Decimal is not a number. This works for all 2^56 NaN values.

isNumberDecimalBool

inherited from Num.isNumber

negateDecimalDecimal
oneDecimal
pure native 0x100L

The canonical Decimal 1

signDecimalInt

the sign of a Decimal (either -1, 0 or 1)

subtractDecimalDecimalDecimal

inherited from Num.subtract

zeroDecimal
pure native 0L

The canonical Decimal 0

instance Ord Decimal

Member Functions

!=DecimalDecimalBool
infix  7
<DecimalDecimalBool
infix  9
<=DecimalDecimalBool
infix  9
<=>DecimalDecimalOrdering
infix  8
==DecimalDecimalBool
infix  7
>DecimalDecimalBool
infix  9
>=DecimalDecimalBool
infix  9
compareDecimalDecimalOrdering
infix  8

inherited from Ord.compare

hashCodeDecimalInt
maxDecimalDecimalDecimal

inherited from Ord.max

minDecimalDecimalDecimal

inherited from Ord.min

instance Ord Positive

Member Functions

!=PositivePositiveBool
infix  7
<PositivePositiveBool
infix  9
<=PositivePositiveBool
infix  9
<=>PositivePositiveOrdering
infix  8
==PositivePositiveBool
infix  7
>PositivePositiveBool
infix  9
>=PositivePositiveBool
infix  9
comparePositivePositiveOrdering
infix  8

inherited from Ord.compare

hashCodePositiveInt
maxPositivePositivePositive

inherited from Ord.max

minPositivePositivePositive

inherited from Ord.min

instance Show Positive

Member Functions

displayPositiveString

inherited from Show.display

showPositiveString
showCharsPositive → [Char]

inherited from Show.showChars

showList[Positive]StringString

inherited from Show.showList

showsPrecIntPositiveStringString

inherited from Show.showsPrec

showsubPositiveString

inherited from Show.showsub

Functions and Values by Type

[Positive] → StringString

Show_Positive.showList

PositivePositivePositive

addP, diffP, mulP, Ord_Positive.min, Ord_Positive.max

PositivePositiveBool

Ord_Positive.>=, Ord_Positive.>, Ord_Positive.!=, Ord_Positive.<, Ord_Positive.<=, Ord_Positive.==

PositivePositiveOrdering

compareP, Ord_Positive.compare, Ord_Positive.<=>

PositiveString

Show_Positive.showsub, Show_Positive.display, Show_Positive.show

Positive → [Char]

Show_Positive.showChars

PositivePositive

normLeft, normLeftPositive, normRight, recipP, ulpP

PositiveBool

Positive.isNaN, Positive.isZero

PositiveInt

sigDigits, Ord_Positive.hashCode, Positive.exponent

PositiveLong

Positive.toBits, Positive.coefficient

IntPositiveStringString

Show_Positive.showsPrec

IntPositiveDecimal

decimal

IntDecimal

Num_Decimal.fromInt

IntegerDecimal

Num_Decimal.fromInteger

LongIntPositive

packResult, Positive.pack

LongPositive

Positive.fromBits

LongInt

leadingZeroes, relevantBits

LongLong

divu10, mulu10, remu10

DecimalDecimalBool

Ord_Decimal.>=, Ord_Decimal.>, Ord_Decimal.!=, Ord_Decimal.<, Ord_Decimal.<=, Ord_Decimal.==

DecimalDecimalOrdering

compareD, Ord_Decimal.compare, Ord_Decimal.<=>

DecimalDecimalDecimal

Num_Decimal.subtract, Num_Decimal.-, Num_Decimal.*, Num_Decimal.+, Ord_Decimal.min, Ord_Decimal.max

DecimalPositive

positive

DecimalBool

Num_Decimal.isNumber, Num_Decimal.isInfinite

DecimalInt

Ord_Decimal.hashCode

DecimalDecimal

nextDown, nextUp, normLeftDecimal, reciprocal, ulp, Num_Decimal.negate, Num_Decimal.abs

Positive

twoP, Positive.zero, Positive.one, Positive.nan

Int

Positive.minExponent, Positive.maxExponent

Long

coeffExpansionMax, expansionMax, Positive.minCoefficient, Positive.maxCoefficient

(Enum α, Integral α) ⇒ α → α → [(α, Decimal, Decimal)]

recipCheck

Valid HTML 4.01 Strict