Legend has it that after the ancient Greek Hippasus shared with his fellow travelers the elegant proof [1] that the square root of 2 is not a rational number, he was thrown off the ship by Pythagoreans outraged that such numbers should exist. Hippasus subsequently drowned. Whatever catharsis was released by his death did not change the fact that mathematically sqrt(2) cannot be exactly represented by the ratio of two integers.

Rational numbers are simple and elegant. However, in many areas we cannot limit ourselves to dealing with rational numbers since values like sqrt(2) cannot be accommodated. To greatly abbreviate the development of different kinds of numbers, real numbers are commonly used, despite their complexities, since they contain their limits, meaning that transcendental values like pi are inside the system.

Floating-point arithmetic is a systematic approximation to real arithmetic, an approximation with pragmatic compromises to facilitate calculation on computers. Floating-point numbers can represent numbers over vast scales and are (typically) fixed-sized. These aspects of floating-point arithmetic force most field axioms to fail to hold, field axioms being the familiar properties of arithmetic such as addition being associative ((a+b) + c == a + (b+c)).

Other fixed-size approximations that have been explored, such as fixed-slash and floating-slash arithmetic, have been found to have worse computational shortcomings than floating-point arithmetic.

It is true that using a binary floating-point representation rather than a decimal floating-point representation can cause additional surprises since 1/10 is not exactly representable in binary. However, all the field axioms that fail to hold for binary floating-point arithmetic also fail to hold for decimal floating-point arithmetic. In addition, the distances between adjacent decimal numbers makes a larger relative jump (ten-fold) across exponent boundaries than for binary (doubling).

The IEEE 754-2008 standard incorporated decimal arithmetic into an update of the 1985 version of the standard. This included fixed-size 64 and 128 bit decimal formats, amenable for hardware support. However, few architectures have added such support.

Moreover, the roundoff errors from floating-point computation are only one source of errors in a computation. *Even if arithmetic were done exactly, numerical analysis would still be needed.* As numerical analyst Nick Trefethen has said "If rounding errors vanished, 95% of numerical analysis would remain." For example, exact arithmetic does not remove modeling error, where the model does have sufficient fidelity with reality. Many calculations involve sums of an infinite number of decreasing terms so truncation errors occurs for the tail of the total sum once the terms are no longer included.

The bugs have you filed and the emails you have sent to this alias are all known situations and have all received responses:

    JDK-8190947 -- Insufficient arithmetic Behaviour
    Closed -- will not fix, including citations to additional explanations of floating-point.

    JDK-8197995 - BigDecimal and BigInteger Defaulting Behaviour
    Closed -- not an issue, long-existing documentation describes exactly how to avoid the reported problem.

    JDK-8190991 - Forward and Inverse operations accuracy.
    Closed -- not an issue. With fixed-precision, it is not possible to invert operations over the entire domain,    as previously discussed on this list http://mail.openjdk.java.net/pipermail/core-libs-dev/2017-December/050393.html.

    JDK-8190946 - There is no elementary functions support for BigDecimal and BigInteger.     Closed as a duplicate of  JDK-4297957, which in turn was created in 1999 and closed as will not fix in 2006.

Repeatedly ignoring these responses and the reasons given for them will not make advancing your cause easier and wastes the time of those crafting the replies.

To examine a few of these more closely, for JDK-8190991: "Forward and Inverse operations accuracy" the responses give examples where for a fixed-precision result, the function cannot be exacted inverted even in the case where the true function is monotonically increasing (where it is defined), like square root. The concrete example previously sent to core libs: sqrt on the domain [1, 2) is in the range [1, ~1.4). From the pigeon-hole principle, this cannot be in inverted in the same precision since (of necessity) multiple elements of the domain map to the same element in the domain. In fact, a majority of elements of range must have two or more corresponding domain elements.

For JDK-8190946: "There is no elementary functions support for BigDecimal and BigInteger", it is a true observation that BigDecimal and BigInteger offer few elementary math functions, many fewer functions than are supported for double in java.lang.{Math, StrictMath}. It is also true that a larger suite of math library methods for BigDecimal would be useful to some users. However, the mere fact that a set of new library methods would be useful for some users is *not* sufficient cause to have the JDK team work to develop, test, and maintain such a library. It is perfectly acceptable and in many ways preferable for limited-use libraries to be developed outside of the JDK and not shipped as part of the JDK.

One of the use-cases for the value type changes being worked on in Project Valhalla is lower-overhead for numerical types, such as BigDecimal and BigInteger and potential classes like complex, etc. IMO, it would also be reasonable to have syntactic support for operators on such types.

There are no prospects for a fundamental redefinition of the floating-point semantics of the Java language and VM. It is possible a faster and looser mode will be defined at some point, but altering the default is extremely unlikely. Long-term, decimal-based arithmetic (and other kinds of arithmetic) may get better support as a consequence of the features in Valhalla. Filing additional bugs or additional emails to this alias will not change any of this or make it happen faster.

A few notes on what this mailing list is and is not. This list and other lists under of the OpenJDK umbrella are forums for people participating in OpenJDK development and who want to be informed about OpenJDK development. These lists are not a free support channel. These lists are not a forum to drop in, issue demands for large projects without so much as an offer of assistance, and then check back a few months later to see why more progress hasn't been made.


[1] Assume sqrt(2) is a rational in lowest terms, p/q. Then, by definition, 2 = (p^2)/(q^2) and therefor 2(q^2) = p^2. Consequently p^2 is even which implies p is even as well. Let r = p/2; r is an integer. p^2 = (2r)^2 = 4r^2. Substituting, 2(q^2) = 4(r^2), reducing q^2 = 2(r^2). Therefore, q^2 is even and q is even as well. However, we have reached a contradiction. If both p and q are even, then p/q is *not* in lowest terms. Therefore, there is no rational number which is the square root of 2.

Reply via email to