Every compatible version of the Java OpenJDK, from every vendor on the internet, has one overall problem.
Arithmetic performed by operators on number values/types, being float and double, are able to gain
denormal or pronormal values, 'Floating Point Errors', alongside the same, produced by method calls
made on java.lang.StrictMath. This is is always quoted as being because of Java adherence to standard IEEE 754,
which has a 2008 version, and has a more recent but non-free paper released in 2019.
Programmers need range accurate integer and decimal mathematics, at the roots of their language, certainly if that language
is to be a higher level language than Assembly or C. While there is the workaround approach, involving BigDecimal and
BigInteger, and another approach that supplies a calculator class, the big-math library,
https://github.com/eobermuhlner/big-math, using and rely on these
stop-gap, work-around solutions is a poor approach. They are larger in memory than needed; slower, messier in
source code to program, debug, understand and edit, exclude their own access to operator syntax, and they are also
never reified with default Java library classes or interfaces.
IEEE 754, alongside floating point arithmetic, mentions traps, state exceptions and flags, phenomena that as of OpenJDK 17
Java has not adopted. It has been the attitude that because 754 doesn't stipulated what happens with underflow or overflow,
aside from traps, state exceptions or flags, nor does it stipulate that it is a base 10 system on top of a binary one exactly, that
therefore, because of these, underflow and overflow aren't (and can't be) bugs, by "definition of IEEE 754". In fact, because
this seems to mean that 754 is not stated to be either a base 10 or base 2 system, that therefore from base 10's point of view,
it could be either. This leads to one real view that it is incoherent, and therefore that it doesn't technically seem to resolve
objectively, anywhere. IEEE 754 isn't strict or specific enough for base 10 or overflow/underflow, and trying to justify
too closely too it creates problems with no solutions.
See IEEE 754 2008 https://irem.univ-reunion.fr/IMG/pdf/ieee-754-2008.pdf
Pp 2, 1.5 Programming Environment Considerations, the first sentence.
This state of affairs has made floating point correction, at the locale of the Vendor and of Java ubiquity itself, impossible.
Notwistanding calculator classes and comparisons, consider the following three code fragments:
**//----------------------------------------------------------
//The C Language. Arithmetic only, no comparisons.
#include <stdio.h>
int main()
{
printf("Program has started...");
printf("\n");
printf("\n");
double a = 0.1D;
double b = 0.1D;
double c = a*b;
printf("%lf",c);
printf("\n");
printf("\n");
float d = 0.1F;
float e = 0.1F;
float f = d*e;
printf("%lf",f);
printf("\n");
printf("\n");
printf("Program has Finished.");
return 0;
}
/*
Program has started...
0.010000
0.010000
Program has Finished.
*/
//----------------------------------------------------------
//The C++ Language. Arithmetic only, no comparisons.
#include <iostream>
using namespace std;
int main()
{
cout << "Program has started..." << endl;
double a = 0.1D;
double b = 0.1D;
double c = a*b;
cout << endl << c << endl << endl;
float d = 0.1F;
float e = 0.1F;
float f = d*e;
cout << f << endl << endl;
cout << "Program has Finished.";
return 0;
}
/*
Program has started...
0.01
0.01
Program has Finished.*/
//----------------------------------------------------------
//The Java Language. Arithmetic only, no comparisons.
import static java.lang.System.*;
public class Start
{
public static void main(String ... args)
{
out.println("Program has started...");
double a = 0.1D;
double b = 0.1D;
double c = a*b;
out.println();
out.println(c);
float d = 0.1F;
float e = 0.1F;
float f = d*e;
out.println();
out.println(f);
out.println();
out.println("Program has Finished.");
}}
/*
Program has started...
0.010000000000000002
0.010000001
Program has Finished.*/
//----------------------------------------------------------**
Other people are aware of these shortfalls, which have gone on for too long a time. Which for programmers needing
continous mathematical types, in areas of 2D graphics and 3D, has turned length of time into length of misery.
See: https://people.eecs.berkeley.edu/~wkahan/JAVAhurt.pdf, and
https://people.eecs.berkeley.edu/~wkahan/ARITH_17.pdf.
While Java has comparators ==, !=, >,<,>=,<= working correctly on float and double (which C++ hasn't), C++ does have
range accurate, base 10 decimal floating point arithmetic on its float, double, long float, long double types, which
does prove that this is possible, and in a fast manner. C decimal arithmetic behaves in terms of its ranges. I am aware
that C++ taps into SSE, or equivalent, additional hardware bit registers, and similar, to deal with binary carries
past the range end(s) of a floating point type, so that the final base 10 digit calculated and submitted, even if it is straddling
the end of the bit range, still gets included, in base 10, entirely accurately, with no more pronormal and no less denormal
values. See https://en.wikipedia.org/wiki/Streaming_SIMD_Extensions.
Clearly it is possible to have reciprocal operations resolving to the perfect state of a previous value in place, which Java
already has implemented, internally.
I am aware the Amazon Corretto has been and is willing to patch its JRE/JVM to add new feature and improvements to their
Corretto Java. It wish to propose and request the following:
- Is it possible for 64 bit Corretto, on all its Hardware/OS platforms, to produce a patch for Corretto, at least compatible
with its most recent publically available, stable, version, but compatible moving forwards, that makes its Java floating
point arithmetic and StrictMath (or equivalent) operations and calls (and any necessary closely bound class and interface
relationships) entirely range accurate, by use of the (now ubiquitous) SSE type hardware, or similar?
- Such a patch could just alter the default for all execution. It could also attenuate to a runtime switch, or manifest line
entry level approach. It might even approach to some special annotations approach, which alter denormal and pronormal
mode on an off on variables, classes, interfaces, and even data, if this proves to be fast enough. Or an aggregate of all these could
be implemented.
- Can someone in Amazon, actively involved with Corretto Java, kindly respond, with an imminent response or recommendation,
only in terms of Java floating mathematics, itself?