Why does we still need StrictMath?

Victor Williams Stafusa da Silva victorwssilva at gmail.com
Sun May 8 05:54:38 UTC 2022


JEP 306 was already delivered some time ago. And with it, we get rid of the
need of that nasty strictfp and the need to have both loose FP and strict
FP.

However, the class java.lang.StrictMath is still around as a normal class,
almost mirroring java.lang.Math, and I really can't understand why.

The javadocs of the Math class says:

"<p>Unlike some of the numeric methods of class {@link java.lang.StrictMath
StrictMath}, all implementations of the equivalent functions of class
{@code Math} are not defined to return the bit-for-bit same results.  This
relaxation permits better-performing implementations where strict
reproducibility is not required.

<p>By default many of the {@code Math} methods simply call the equivalent
method in {@code StrictMath} for their implementation.  Code generators are
encouraged to use platform-specific native libraries or microprocessor
instructions, where available, to provide higher-performance
implementations of {@code Math} methods.  Such higher-performance
implementations still must conform to the specification for {@code Math}."

This seems to be a good motivation on a first look. But:

[a] Eliminating such a thing was not one of the reasons why JEP 306 was
conceived?

[b] Wasn't high-performance with poor-precision one of the things from the
ancient J2SE 1.2 and 1.3 days that isn't a concern anymore because nowadays
processors are much better at FP and we restored always-strict behaviour?

[c] As long as the always-strict FP semantics are respected, if Math
methods could be replaced by higher-performance implementations, why
wouldn't the same apply to StrictMath?

[d] Can someone provide a test case that shows a difference in the
behaviour of Math and StrictMath using some modern hardware and some modern
JVM where JEP 306 was delivered? And if so, is there a reason to call it a
feature instead of a bug?

It might seem that I am being a bit arrogant by making those questions, but
if after JEP 306 there could still be differences in the results produced
by Math and StrictMath, I think that many people would like to know.

Many people (like me right now) assume (and assumptions might be false
sometimes) that since JEP 306 was delivered, there is no need anymore to
have any concern about loose or strict math and with that any concern for
having to carefully choose between Math or StrictMath because both would
have exactly the same behaviour. Many people think/assume that the
motivation that led to StrictMath being created was due to the absence of
the strictfp modifier in the Math class, but since strictfp is a no-op now
and gone from the StrictMath class, then StrictMath would behave exactly
the same as Math.

So, if even after JEP 306 was delivered, there is still any meaningful
observable difference between Math and StrictMath, I think that it should
be emphasized in the javadocs.

Looking at the source code of Math and StrictMath, some methods of Math
delegate to the same method in StrictMath and some methods do the other way
around. Only three methods feature divergent implementations where one
doesn't just delegate to the other. By using delegation, it is ensured that
the methods in one class perfectly mirrors the behaviour of the same method
in the other class (barring stacktraces, SOE and internal or
vendor-specific JVM blackmagic).

[e] If StrictMath is still needed and could produce different results than
Math in some modern hardware, then by the javadocs, it seems to imply that
Math should always delegate to StrictMath and never the other way around.
Why is it not always the case? I think that the answer is simply because
the StrictMath class was largely left unchanged and that delegating in one
way or in the other could then produce a difference when the strictfp
modifier was there, but is there a better reason than that?

If, however, there is no meaningful difference in the results of Math and
StrictMath, my proposal is pretty simple and bold: Deprecate the StrictMath
class and make all its methods simply delegating to Math! Let's all just
use the good old Math class and make our lives better and simpler.

Further, I said that there are three methods that feature divergent
implementations. They are those:

public static double random()
public static double copySign(double magnitude, double sign)
public static float copySign(float magnitude, float sign)

The fact that there are two random() implementations implies the creation
of two java.util.Random instances instead of one. This seems to be a small
bug for me, but one with no observable and/or discernible behavioral
differences. One of them should delegate to the other like the other
methods.

About the copySign methods, the javadocs tell that the difference is the
handling of NaN. This seems to be a nasty difference, since all of the
other methods are expected by users to feature the exact same behaviour in
both classes. My suggestion would be to provide copySignCheckNaN methods in
the Math class or something like.


More information about the core-libs-dev mailing list