Proposal for Decimal64 and Decimal128 value-based classes
Joe Darcy
joe.darcy at oracle.com
Tue Mar 30 19:56:33 UTC 2021
Hi Raffaello,
On 3/29/2021 1:14 PM, Raffaello Giulietti wrote:
> Hello,
>
> I'm experimenting with an implementation of Decimal64 and Decimal128,
> two standard IEEE 754-2019 formats supporting, well, decimal floating
> point numbers of up to 16 resp 34 decimal digits.
Fun project!
>
> While BigDecimal can simulate most finite number computations on these
> formats by passing MathContext.DECIMAL64 and MathContext.DECIMAL128,
> resp., to the arithmetic operations, this approach has some
> shortcomings wrt to the standard:
> * Like the binary formats (float and double in Java), the standard
> mandates signed zeroes, signed infinities and NaNs for the decimal
> formats as well, while BigDecimal has neither.
Quite right; those differences were recently (if belatedly) documented
in JDK 17 (8261366: Add discussion of IEEE 754 to BigDecimal).
> * BigDecimal is not a final class, so is not (and can never be)
> value-based.
Yep; as discussed in "Effective Java" the non-final-ness of the class
was recognized as a mistake after it was in the platform, but it is not
something we are likely to change now. As an aside, a happy accident of
the ability of BigDecimal to be subclassed was allowing easier
adaptation to changes in toString output that had an unexpectedly large
behavioral compatibility impact in JDK 5.0.
> * BigDecimal needs support from BigInteger (another non final, non
> value-based class).
>
> On the other hand, classes Decimal64 and Decimal128:
> * Are value-based and can be declared to be primitive in a future
> version of OpenJDK, once Valhalla is completed.
> * Require 12 and 20 bytes, resp, of storage in the Valhalla model of
> primitive objects and have no references to other identity or
> primitive objects.
> * Support the signed zeroes, the infinities and the NaNs.
> * Currently support the 4 fundamental operations (+ - * /) according
> to the standard and will support remainder, square root, comparisons,
> etc. and the conversions listed in the standard.
Assuming you have DecimalN <-> BigDecimal conversions, the BigDecimal
type should be usable for testing at least. For in-range values not near
the exponent range, the scale (exponent) and significand for finite and
nonzero values should be the same for the basic arithmetic operations
and square root in DecimalN and BigDecimal.
(Around the limits of the exponent range, there are subnormal and
"supernormal" results where the rounding of the significand interacts
with the exponent computation. This would make it a bit tricky to
offload BigDecimal computations in range of, say, a Decimal128 to a
hardware implementation where one was available.)
Fixed-size decimal computations have an interesting design space to
explore in terms of trading off memory compactness and computational
cost. For example, the IEEE 754 spec details two different encodings of
three decimal digits in 10 bits. However, it is not strictly necessary
for each operation to produce results whose internal storage maps to an
"interchange format," in the terminology of 754. It would be possible to
keep the significand encoded as normal integers and only produce an
interchange representation on something akin to a serialization event.
I understand hardware implementations of FPUs will use these sort of
techniques and also have architectural-invisible bits indicating what
kind of value a floating-point number is. For example, the beginning of
many math library functions starts with "Handle NaN cases," ... "Handle
infinity case" ... "Handle zero case" ... Sometimes the handling falls
out naturally and doesn't require explicit testing, but in the cases
that does not occur, it can be cheaper to have the "isFoo" bit already
computed.
> * Could be extended to support the (rather cumbersome) exceptions
> handling of the standard.
> * There's no plan to support transcendental functions, as the aim is
> to have numerical classes for business applications, not scientific or
> engineering purposes.
> * Are faster than the (incomplete) simulation with BigDecimal, 1x-5x
> in the current incarnations.
>
>
> I would be glad to contribute the code to the OpenJDK provided there
> is a genuine interest from the community and a reviewer willing to
> sponsor my effort. (I guess the best candidate for this role would be
> Joe Darcy from what I can read in this mailing list.)
>
At least for the time being, I don't think the OpenJDK (at least the
main project) would be the best home for such code. As you're noted,
post Valhalla having such a type in the JDK becomes more interesting
from a performance perspective.
Thanks,
-Joe
More information about the core-libs-dev
mailing list