A candidate implementation of decimal numbers (arbitrary-precision
floating-point numbers) is available for review at
https://github.com/andersonpd/eris/tree/master/eris/decimal. This is a substantial rework of an earlier implementation which was located at
https://github.com/andersonpd/decimal.

This is a D language implementation of the General Decimal Arithmetic Specification (http://www.speleotrove.com/decimal/decarith.pdf), which is compliant with IEEE-754 and other standards as noted in the specification.

The current implementation is not complete; there are a lot of TODOs and NOTEs scattered throughout the code, but all the arithmetic and miscellaneous operations listed in the spec are working, along with decimal versions of most of the functions and constants in std.math. I think it is far enough along for
effective review.

Briefly, this software adds the capability of properly rounded
arbitrary-precision floating-point arithmetic to the D language. All arithmetic operations are governed by a "context", which specifies the precision (number of decimal digits) and rounding mode for the operations. This same functionality exists in most modern computer languages (for example, java.math.BigDecimal). Unlike Java, however, which uses function syntax for arithmetic ops (add(BigDecimal, BigDecimal), etc.), in D the same arithmetic operators that
work for floats or doubles work for decimal numbers. (Of course!)

In this implementation decimal numbers having different contexts are different types. The types are specified using template parameters for the precision,
maximum exponent value and rounding mode. This means that
Decimal!(9,99,Rounding.HALF_EVEN) is a different type than
Decimal!(19,199,Rounding.HALF_DOWN). They are largely interoperable, however.
Different decimal types can be cast to and from each
other.

There are three standard decimal structs which fit into 32-, 64- and 128-bits of memory, with 7, 16 and 34 digit precision, respectively. These are used for compact storage; they are converted to their corresponding decimal numbers for calculation. They bear the same relation to decimal numbers as Walter's
half-float type does to floats.
(http://www.drdobbs.com/cpp/implementing-half-floats-in-d/240146674).
Implementation of these still needs a little work, and will be added to github
very shortly.

Major TODO items:

1) The current underlying integer type uses my own big integer struct (eris.integer.extended) rather than std.bigint. This was mainly due to problems with constness and CTFE of BigInts. These problems have since been resolved, but I didn't want to switch over to BigInts until everything was working for fear of
introducing new bugs.

2) Integration of Decimal32, Decimal64 and Decimal128 structs are not complete.
(See above.)

3) Conversion to and from floats, doubles and reals is currently working but it is slow. (Conversion is through strings: double to string to decimal and vice
versa.)

4) Still incomplete implementations of some functions in decimal.math: expm1,
acosh, atanh, possibly others.

5) More unit tests (always!).

Reply via email to