Java Numerics

Jerome Coonen jeromeabe.com
Sun Feb 2 22:55:54 PST 1997


Dear Colleagues,

In his recent posting, Doug Priest wrote that

 >> Coonen laments the fact that Java as it is defined seems not to be a
 >> good environment for serious scientific computing.

I would prefer to think that I argued in my Note on Java Numerics that Java
is not yet the BEST environment for numerical computation, especially for the
tens of millions of users of fpus which use extended values for intermediate
calculations.  I attempted to show that the flaw in the design was motivated
by the strict demand for bit-for-bit reproducible results for all
computations across all platforms -- a demand that is neither numerically
necessary nor commercially feasible.  This letter focuses on changes to
the Java spec that would serve a broad numerical community without
compromising robustness nor portability.

Doug Priest continued to present a compelling example of the occasional
need for strict coercion to a given data format.  This is a technique used
to "split" a number into lower-precision pieces.  It's widely acknowledged
to be a Good Thing; I merely request that it not be the Only Thing.

 >> The choice that the designers of Java made sacrifices efficiency but
 >> may well save a lot of programmers from the embarrassment (or worse)
 >> of not knowing that
 >> 
 >>         y = (x + 6755399441055744.0) - 6755399441055744.0
 >> 
 >> and
 >> 
 >>         y = x + 6755399441055744.0
 >>         y = y - 6755399441055744.0
 >>
 >> don't mean the same thing.

I will try to show that there's no need to sacrifice efficiency and that the
only reason for a programmer not to know the fate of the right-hand side is
for want of asking.  Other programmers might be disappointed or dismayed
(depending on their platform) that the simple expression

   z = (a * x) / (b * y);
 
leaves z a NaN or infinity, when the mathematical ratio is exactly 2.
 
EXPRESSION EVALUATION
 
Here lies the crux of the disagreement.  Arguments like Doug Priest's show
that strict coercion of intermediates -- whether by casting, assignment, or
control of expression evaluation -- is vital to certain numerical techniques.
My arguments from the Note show that forcing strict evaluation to float or
double compromises performance on virtually every calculation performed by
extended-based processors.

The C9X proposed revision of Standard C offers an alternative to one-size-
fits-all evaluation.  As Jim Thomas pointed out in his recent note, cries by
some of "unpredictability" and "nondeterministic behavior" are overstated.
He points out that C9X permits three evaluation styles:

 >> 1. evaluate float expressions to float, double to double, and long
 >>    double to long double
 >> 2. evaluate float and double expressions to double and long double to
 >>    long double
 >> 3. evaluate them all to long double

A program can ask what style is in effect at translation time.  Method 3
applies to extended-based archtictures like x86.  Method 2 applies to
PowerPC.  Method 1 applies to a variety of other processors supporting
IEEE arithmetic.

This flexibility captures the spirit of IEEE 754, which explicitly
recommended hardware support of an extended type.  During deliberations on
754, it was argued that the use of extendeds FOR INTERMEDIATE CALCULATIONS
would defend some naive calculations against precision and range problems,
would offer extra capability to experts, and, most importantly, not unduly
compromise portability of programs designed for float or double calculation.

But poor support by high-level languages has given the extended formats a
bad reputation.  Some compilers set "precision control" bits to force
intermediates to be rounded to double.  Others ignore explicit casts to a
narrower type.  Many offer no "long double" type to explicitly declare
extended variables.

It's my experience that, too often, compiler implementors appeal to a
questionable purity of language to excuse "simplifications" that compromise
numerical applications.

With Java, however, there is an opportunity to support robust and portable
calculation across the diversity of IEEE platforms.  It's my hope that
Java's designers will look closely at this issue.  With the announcement of
one company's intention to deliver IMSL libraries in Java, and the
announcement of an ACM workshop on Java for Science and Engineering
Computation, Java promises to be an important language for numerical
computation.  Designing its expression evaluation for the best balance
of performance, robustness, predictability, and portability would be a boon
not only for Java programmers, but for C, C++, and FORTRAN programmers,
whose compiler vendors might be induced to meet the high standard set by Java.

REPRODUCIBLE RESULTS

Discussion to date suggests that the urge of Java's designers to limit
expression evaluation to just one style is driven by the demand for
reproducible results for EVERY calculation across all platforms.

This means, for example, that the method java.lang.Math.sin would compute
the same approximation to the mathematical sine function on all platforms.
As Guy Steele pointed out in an off-line note,

 >> [Java] requires that java.lang.Math.sin, java.lang.Math.log, etc.,
 >> be rounded as fdlibm [Sun's publicly available math function library]
 >> rounds them. There is no objection to provision of alternate
 >> implementations as long as they have different names.

Fdlibm is an excellent piece of technology, but I claim that the numerical
community wants accurate results fast, not an arbitrary definition of
correctness that is blind to performance.  How will the IMSL codes be
ported to the Java environment, where they will be subjected to performance
benchmarks?  Anyone hoping to sell products based on performance will be
forced to resort to some "java.lang.FAST.Math.sin" in order to exploit
Pentium's highly accurate fsin instruction or PowerPC's all-but-correctly
rounded library that exploits fused mul-add.  And what if fdlibm must
change slightly; what is correct then?

Results will be reproducible until the first benchmark is run, when a
balance of the realities of the marketplace and the real needs of numerical
programmers will drive Java practice to a less pure but more useful plane.

Because exact reproducibility of results drives the overly strict
expression evaluation style of the current Java spec, I encourage the Java
community to explore this issue fully with numerical and business folks.
I consider the current definition of java.lang.Math.sin far less desirable
to the numerical community than the chance to exploit fast, accurate
evaluation across all Java platforms.

-Jerome Coonen



More information about the Numeric-interest mailing list