Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [temurin-dev] Floating Point Arithmetic and Math Function/Method denormal and pronormal errors?

I refer you to Martijn's response to your same request sent to the adoptium-wg mailing list three days ago.


Tim



On 05/05/2022 09:02, A Z wrote:

Dear Temurin,



Java JDK/JRE Java runtimes generate floating point arithmetic or java.lang.StrictMath denormal and pronormal values as a result of source code like this. They are an error phenomenon which can and aught be fixed:


/*

//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...");

out.println();

float a = 0.1F;

float b = 0.1F;

float c = a*b;

out.println(c);

double d = 0.1D;

double e = 0.1D;

double f = d*e;

out.println();

out.println(f);

out.println();

out.println("Program has Finished.");

}}


*/

/* Program has started...


0.010000000000000002


0.010000001


[0.01]


Program has Finished.*/


IEE 754 doesn't specifically say anything about the base 10 digit degradation that can happen at the right hand side of floating point decimal number type variables or data. In the OpenJDK, float and double are the main examples, however a similar problem occurs with java.lang.StrictMath method calls. However all examples like this are logic errors, that need to be repaired in either a default or mutual way, simply because denary accuracy is required out of a compiled and running Java program, either at its conclusion or some mid point. The Computer hardware that the author has in mind is the Desktop PC, running any ubiquitous operating system, or as configured as a database or internet server.


Workarounds are used, being BigInteger, BigDecimal, and big-math in java. They introduce an entire tier to the Java software which isn't ultimately needed. They are slow and produce an avoidable loss in speed, are larger in RAM, and don't allow the use of arithmetic operator source code syntax. Things that developers and their programs need. The IEEE should include or state something new in its standard 754 to encourage software vendor(s) to act differently, but if it doesn't, the vendor(s) will have to act on their own.


What seems to be required is one of two approaches. The original equation from IEEE 754 can be adjusted or disregarded; instead of being followed into the negative exponents region, the exponent of 2 can always be kept positive, both for integers and decimals similarly; the curve should reflect itself for integers and decimals through the vertical axis. In this manner, reciprocal powers of two are not generated, and never create problems. This scheme for floating point is an enhanced mirror of fixed point binary numerics. However, by following this ideal I have calculated an approx. 18% reduction in decimal place range for Java float and an approx. 5% decimal place range redution for Java double.


The other approach is patch the present circumstances with available hardware bit registers. Having two range limits for float and double; values range limits, and right hand side consideration range limits for decimals and their relationship to binary. This has existed as extra SSE registers, and their descendants; all of such does exist in the vast majority of relevant and ubiquitous, compatible CPU hardware. Surely those registers can be leveraged to solve these values and their calculation problems. This way, accuracy of all possible decimal values can be maintained, and degrading of the decimal digits can be kept outside the decimal value range limit, with no range reduction at all at the decimal end. Consider what GNU C++ has done with SSE and floating point decimal accuracy:


//----------------------------------------------------------

//The C++ Language. Arithmetic only, no comparisons.

#include <iostream>

#include <iomanip>


using namespace std;


int main()

{

cout << "Program has started..." << endl;

setprecision(-9);

float a = 0.1F;

float b = 0.1F;

float c = a*b;

cout << endl << c << endl;

/*

setprecision(2); //Multiplication count from left to right.

d = 0.1F;

e = 0.1F;

f = d*e;

cout << endl << f << endl;

*/

setprecision(-18);

double d = 0.1D;

double e = 0.1D;

double f = d*e;

cout << endl << f << endl;

cout << endl;

/*

cout << setprecision(2); //Multiplication count from left to right.

a = 0.1D;

b = 0.1D;

c = a*b;

cout << endl << c << endl << endl;

*/

cout << "Program has Finished.";

return 0;

}

//----------------------------------------------------------

Consider the following, the IEEE 754 floating point binary number formula:


n(2)=(-1)s × m(2) × 2(e(2) – 127)


as is defined by the mantissa of the registry, the exponent of the registry, the sign of the number and the number, which is now binary, for a 32 bit or 64 bit hardware registry.


There is the option to reflect the positive part of the curve, however that will reduce the range of the number types involved, because this reduces numeric density within the curve. But it will mean that no denormal or pronormal decimal values can occur, and that the precalculating for number mapping will be more efficient for decimals than as present. It would be most compatible to use an SSE an additional bit registers approach to do further correct calculating and to offset the range of binary to decimal degredation, the way that GNU C++ has achieved.


However, things can be done compatabily. There could be a patch program, separate to the main Java download. Trying not to change how the language compiled, there could be a runtime switch which can be wrapped around previous Java code. There could be a manifest file entry for (.jar,.war,.ear) files. There could be an overhead static class that can be called for code spaces, or all code spaces beneath a main method, a Thread start method, Futures or any similar. Something similar should be possible by using some original annotations. But so long as the contents of a float and a double can read and write over one another, both modes of operation could be used at the same time if things were set up consistently enough. All that is presuming that the bold step of total default change isn't to be taken. Since the floating point errors occur in the decimal unit in the last place, and that any such result breaks the contiguous range property to a ranged denary number line, who could possibly, in any meaningful way, be needing and relying on a floating point error situation?


Is the Temurin able to update its JDK and JRE offerings for all platforms, to either repair at default or at compatibility, these floating point errors?




Can you please reply to me here in English, or at my secure secured email address,


sminervini.prism@xxxxxxxxxxxxxx


?


We would be thrilled to hear about a positive response!



Yours Sincerely,


Sergio Minervini


S.M.



_______________________________________________
temurin-dev mailing list
temurin-dev@xxxxxxxxxxx
To unsubscribe from this list, visit https://accounts.eclipse.org

Back to the top