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