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

Reply via email to