support for Decimal numbers
unsigned division by 10, using only 8 additions and 10 bit shifts
unsigned modulus 10, using only multiplication, addition and bit shifts
multiplication by 10, with shift and add
this will be inlined, so only use strict variables as argument
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
extract the coefficient from a Positive
This is simply an unsigned right shift by 8
extract the exponent, sign extended in an Int
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).
tell if a Positive is not a number. This works for all 2^56 NaN values.
tell if a Positive is 0. This works for all 255 0 values.
the largest possible coefficient is 72_057_594_037_927_935
the largest exponent is 127
the smalles possible coefficient is 0
the smallest exponent is -127
The canonical not a number value.
Note that there are 2^56 NaN values, all comparing equal.
The canonical Positive 1
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
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
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).
The canonical Positive 0
a coeficient cannot be multiplied by 10 if it is greater than 922337203685477_580
a number greater than this, multiplied by 10, wouldn't fit anymore in the 56 coefficient bits
convert a Positive back to a Decimal with the sign indicated by the first argument
find the representation of a Positive with the smallest coefficient
NaN and 0 come out in their canonical forms
find the representation of a Positive with the greatest coefficient
NaN and 0 come out in their canonical forms
represent a Decimal with the greatest valid coefficient
NaN and 0 come out in their canonical forms
represent a Positive with the greatest valid coefficient
NaN and 0 come out in their canonical forms
find the smallest number that makes a difference when adding it to the given number
given a Decimal x find a Decimal y such that there is no Decimal z with x < z < y
given a Decimal x find a Decimal y such that there is no Decimal z with x > z > y
tell the number of significant digits
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.
add 2 Positive numbers
both numbers must not be NaN
difference between 2 Positive numbers, where the first one must be >= the second one
both numbers must not be NaN
inherited from Num.abs
inherited from Num.isInfinite
tell if a Decimal is not a number. This works for all 2^56 NaN values.
inherited from Num.isNumber
The canonical Decimal 1
the sign of a Decimal (either -1, 0 or 1)
inherited from Num.subtract
The canonical Decimal 0
inherited from Ord.compare
inherited from Ord.max
inherited from Ord.min
inherited from Ord.compare
inherited from Ord.max
inherited from Ord.min
inherited from Show.display
inherited from Show.showChars
inherited from Show.showList
inherited from Show.showsPrec
inherited from Show.showsub
Ord_Positive.>=, Ord_Positive.>, Ord_Positive.!=, Ord_Positive.<, Ord_Positive.<=, Ord_Positive.==
Show_Positive.showsub, Show_Positive.display, Show_Positive.show
Ord_Decimal.>=, Ord_Decimal.>, Ord_Decimal.!=, Ord_Decimal.<, Ord_Decimal.<=, Ord_Decimal.==
Num_Decimal.subtract, Num_Decimal.-, Num_Decimal.*, Num_Decimal.+, Ord_Decimal.min, Ord_Decimal.max
nextDown, nextUp, normLeftDecimal, reciprocal, ulp, Num_Decimal.negate, Num_Decimal.abs
coeffExpansionMax, expansionMax, Positive.minCoefficient, Positive.maxCoefficient