This describes a software implementation of the DEC64 elementary operators. Sources are available for Intel/AMD x64 and ARM64.
dec64.h includes C function prototypes for these functions:
dec64_abs(number: dec64) returns
absolution: dec64
dec64_add(augend: dec64,
addend: dec64) returns sum: dec64
dec64_ceiling(number: dec64)
returns integer: dec64
dec64_coefficient(number:
dec64) returns coefficient: int64
dec64_divide(dividend: dec64,
divisor: dec64)
returns quotient: dec64
dec64_exponent(number: dec64)
returns exponent: int64
dec64_floor(number: dec64) returns
integer: dec64
dec64_integer_divide(dividend:
dec64, divisor: dec64) returns
quotient: dec64
dec64_is_equal(comparahend: dec64,
comparator: dec64) returns
comparison: dec64
dec64_is_false(boolean: dec64)
returns comparison: dec64
dec64_is_integer(number: dec64)
returns comparison: dec64
dec64_is_less(comparahend: dec64,
comparator: dec64) returns
comparison: dec64
dec64_is_nan(number: dec64)
returns comparison: dec64
dec64_is_zero(number: dec64)
returns comparison: dec64
dec64_modulo(dividend: dec64,
divisor: dec64) returns
modulus: dec64
dec64_multiply(multiplicand:
dec64, multiplier: dec64) returns
product: dec64
dec64_neg(number: dec64)
returns negation: dec64
dec64_new(coefficient: int64,
exponent: int64) returns number: dec64
dec64_normal(number: dec64) returns
normalization: dec64
dec64_round(number: dec64,
place: dec64) returns
quantization: dec64
dec64_signum(number: dec64) returns
signature: dec64
dec64_subtract(minuend: dec64,
subtrahend: dec64) returns
difference: dec64
Three types are provided:
dec64
int64
uint64
These constants are also provided:
DEC64_NULL
DEC64_ZERO
DEC64_ONE
DEC64_TWO
DEC64_NEGATIVE_ONE
DEC64_TRUE
DEC64_FALSE
The comparison functions will return either DEC64_TRUE
or DEC64_FALSE
.
nan (not-a-number) is a popular but poorly named concept in
floating-point systems. It is a number value that represents numbers that
are undefined or not representable. DEC64 has
72 057 594 037 927 936 possible nan values. When these functions return a
nan value, they will always return DEC64_NULL
, the
normal nan, regardless of the input.
Two nan values, DEC64_TRUE
and DEC64_FALSE
, are reserved for representing boolean values.
The remaining nan values may be used to hold object pointers or other useful values.
These operations will produce a result of DEC64_NULL
:
dec64_abs(nan) dec64_ceiling(nan) dec64_floor(nan) dec64_neg(nan) dec64_normal(nan) dec64_signum(nan)
These operations will produce a result of DEC64_ZERO
for all
values of n, even if n is nan:
dec64_divide(0, n) dec64_integer_divide(0, n) dec64_modulo(0, n) dec64_multiply(0, n) dec64_multiply(n, 0)
These operations will produce a result of DEC64_NULL
for all
values of n except 0
:
dec64_divide(n, 0) dec64_divide(n, nan) dec64_integer_divide(n, 0) dec64_integer_divide(n, nan) dec64_modulo(n, 0) dec64_modulo(n, nan) dec64_multiply(n, nan) dec64_multiply(nan, n)
These operations will produce a result of DEC64_NULL
for all
values of n:
dec64_add(n, nan) dec64_add(nan, n) dec64_divide(nan, n) dec64_integer_divide(nan, n) dec64_modulo(nan, n) dec64_round(nan, n) dec64_subtract(n, nan) dec64_subtract(nan, n)
DEC64 has 255 zero values. DEC64 treats them as if they are all equal to
each other. The only zero value returned from these functions is the normal
zero, DEC64_ZERO
, which is the same as the native
int64
zero, 0
.
Rounding is to the nearest value. Ties are rounded away from zero. Integer
division is floored. The result of dec64_modulo
has the sign of
the divisor. There is no negative zero.
The absolute value function removes the sign from a number value.
If number is | return |
---|---|
nan | DEC64_NULL |
zero | DEC64_ZERO |
positive | number |
negative | - number |
The add function adds an augend and an addend and
returns the sum. If either is nan, or if the sum is not
representable, then the result is DEC64_NULL
.
The ceiling function returns the smallest integer that is greater than or
equal to the number. If the number is nan,
the result is DEC64_NULL
. If the number is zero, the
result is DEC64_ZERO
. If the number is an integer,
the result is the number.
A DEC64 number is made up of two parts: a coefficient and an exponent.
63 8 | 7 0 |
---|---|
coefficient | exponent |
This function returns the coefficient part as an
int64
.
dec64_coefficient(DEC64_NULL)
returns 0
.
This function divides the dividend by the divisor.
A DEC64 number is made up of two parts: a coefficient and an exponent.
63 8 | 7 0 |
---|---|
coefficient | exponent |
This function returns the exponent part as an int64
.
dec64_exponent(nan)
returns -128
.
Produce the largest integer that is less than or equal to the number. This
is sometimes called the entier
function. In the result, the
exponent will be greater than or equal to zero unless it is
DEC64_NULL
. Numbers with positive exponents will not be
modified, even if the numbers are outside of the safe integer range.
Divide, with a floored integer result. It produces the same result as
dec64_floor(dec64_divide(dividend, divisor))
but can sometimes produce that result more quickly.
Compare two numbers. If they are exactly equal, return
DEC64_TRUE
, otherwise return DEC64_FALSE
. Denormal
zeros are equal but denormal nans are not.
If the boolean is DEC64_FALSE
, the result is DEC64_TRUE
. Otherwise,
the result is DEC64_FALSE
. This is similar to the not function.
If the number contains a non-zero fractional part or if it is
nan, return DEC64_FALSE
. Otherwise, return
DEC64_TRUE
.
Compare two numbers. If the comparahend is less
than the comparator, return DEC64_TRUE
, otherwise
return DEC64_FALSE
. Any nan is greater than any number. All nan values are equal to each other.
The other 3 comparison functions are easily implemented with
dec64_is_less
:
dec64_is_greater(a, b) => dec64_is_less(b, a) dec64_is_greater_or_equal(a, b) => dec64_is_false(dec64_is_less(a, b)) dec64_is_less_or_equal(a, b) => dec64_is_false(dec64_is_less(b, a))
If the number is any nan, return
DEC64_TRUE
, otherwise return DEC64_FALSE
. To test
if a number is the normal DEC64_NULL
, just use ==
.
If the number is any zero, return DEC64_TRUE
,
otherwise return DEC64_FALSE
.
The modulo function produces the same result as
dec64_subtract( dividend, dec64_multiply( dec64_integer_divide(dividend, divisor), divisor ) )
Multiply two numbers.
Negate a number.
A DEC64 number is made up of two parts: a coefficient and an exponent.
63 8 | 7 0 |
---|---|
coefficient | exponent |
Construct a new dec64 number with a coefficient and an exponent.
Normalize the number by making the exponent as close to zero as possible without losing any signficance. Usually normalization is not needed since it does not materially change the value of a number.
Round the number. Ties are rounded away from zero.
The place determines which decimal place to round to. The place should be between -16 and 16. The default is zero.
place | round to nearest |
---|---|
-2 |
cent |
0 |
integer |
3 |
thousand |
6 |
million |
9 |
billion |
If the number is nan, the result is DEC64_NULL
.
If the number is less than zero, the result is
DEC64_NEGATIVE_ONE
. If the number is zero, the result is
DEC64_ZERO
. If the number is greater than zero, the result is
DEC64_ONE
.
Subtract a subtrahend from from a minuend.
dec64.asm
can be processed with Microsoft's ML64.exe.
Visual Studio does not have good defaults for building with MASM, and
apparently provides no documentation. These hints may be useful:
Platform > x64 Solution Explorer > dec64 > Build Dependencies > Build Customizations... > masm
There might be other assemblers that can process this file, but that has not been tested yet.