File | Date | Author | Commit |
---|---|---|---|
dist | 2020-08-18 |
![]() |
[d7d2a7] commit of version 2.3.2 |
src | 2020-08-18 |
![]() |
[d7d2a7] commit of version 2.3.2 |
CHANGELOG.txt | 2020-08-18 |
![]() |
[d7d2a7] commit of version 2.3.2 |
LICENSE-2.0.txt | 2015-12-13 |
![]() |
[6fa0dd] using a more standard layout for files |
README.md | 2020-08-18 |
![]() |
[e78e7c] markdowned README |
TODOLIST.txt | 2020-08-18 |
![]() |
[d7d2a7] commit of version 2.3.2 |
Jafama (Java Fast Math) is a Java library aiming at providing faster versions
of java.lang.Math treatments, at the eventual cost of 1e-15ish accuracy errors
but still handling special cases properly (NaN, +-Infinity, ties, etc.).
It also provides additional features, such as angles normalization methods,
inverse hyperbolic trigonometry, etc.
Apache License V2.0
Java 5+
src/test:
JUnit 3.8.1
src/build:
FastMath, which corresponds to Math API, plus additional treatments.
StrictFastMath, which is a strict version of FastMath (and not a fast version
of StrictMath, which would rather be called FastStrictMath), through
delegation to StrictMath (instead of Math) and use of strictfp.
NumbersUtils, which contains very low level number-related treatments,
and is used by (Strict)FastMath.
Angles normalization methods (normalizeXxx), derived from those used in
java.lang.Math, for which, sadly, no API is provided, letting most users
struggle with their own implementations.
Direct or inverse hyperbolic trigonometry (coshm1, asinh, acosh, acosh1p,
atanh, etc.).
A 3D hypot.
A remainder(...) method, that unlike Math.remainderIEEE(...), returns a value
that is the closest to the dividend, and has the same sign, which is more
consistent across values (doesn't depend on whether values are even or odd),
with intuition, and with how modulo operator (%) behaves.
Various floor/ceiling/rounding/modulo related functions.
(Strict)FastMath.PI_SUP, which is the closest double value superior to
mathematical Pi, such as 2PI_SUP angular span fully covers the trigonometric
circle (2Math.PI doesn't).
Methods with same signature than Math ones, are meant to return
"good" approximations on all range.
Methods terminating with "Fast" are meant to return "good" approximation
on a reduced range only.
Methods terminating with "Quick" are meant to be quick, but do not
return a good approximation, and might only work on a reduced range.
Non-redefined methods Math methods (up to some version of the JDK) are also
available, for easy replacement, even though for some of them, such as for
incrementExact, you might want to stick to Math versions to benefit from
eventual JVM intrinsics.
For performances reasons (for example if wanting to run with no GC),
these treatments do not (unless delegating to JDK) generate objects at run time.
Trigonometric treatments make use of look-up tables: around 1 Mo total,
and initialized lazily and independently, or on first call to
(Strict)FastMath.initTables().
Depending on JVM, or JVM options, these treatments can actually be slower
than Math ones.
In particular, they can be slower if not optimized by the JIT, which you
can see with -Xint JVM option.
Another cause of slowness can be cache-misses on look-up tables.
Also, look-up tables initialization typically takes multiple hundreds of
milliseconds (and is about twice slower in J6 than in J5, and in J7 than in
J6, possibly due to intrinsifications preventing optimizations such as use
of hardware sqrt, and Math delegating to StrictMath with JIT optimizations
not yet up during class load).
As a result, you might want to make these treatments not use tables,
and delegate to corresponding Math methods, when they are available in the
lowest supported Java version, by using the appropriate properties (see below).
About StrictFastMath:
Unlike StrictMath, StrictFastMath is not supposed to behave identically
across versions, and even for a same version it might behave differently
depending on its configuration (properties).
It is just supposed to behave identically for a same version and
configuration, which can still be useful, for example for racily computed
cached values in immutable instances.
Other than strictness and usually lower performances due to strictfp
overhead, the only differences with FastMath are its properties, and
copySign(float,float) and copySign(double,double) semantics.
jafama.usejdk (boolean, default is false):
If true, for redefined methods, as well as their "Fast" or "Quick"
terminated counterparts, instead of using redefined computations,
delegating to Math, when available in required Java version.
jafama.fastlog (boolean, default is false):
If true, using redefined computations for log(double) and
log10(double), else they delegate to Math.log(double) and
Math.log10(double).
False by default because Math.log(double) and Math.log10(double)
seem usually fast (redefined log(double) might be even faster,
but is less accurate).
jafama.fastsqrt (boolean, default is false):
If true, using redefined computation for sqrt(double),
else it delegates to Math.sqrt(double).
False by default because Math.sqrt(double) seems usually fast.
jafama.strict.usejdk (boolean, default is false):
If true, for redefined methods, as well as their "Fast" or "Quick"
terminated counterparts, instead of using redefined computations,
delegating to StrictMath, when available in required Java version.
jafama.strict.fastlog (boolean, default is true):
If true, using redefined computations for log(double) and
log10(double), else they delegate to StrictMath.log(double) and
StrictMath.log10(double).
True by default because StrictMath.log(double) and
StrictMath.log10(double) can be quite slow.
jafama.strict.fastsqrt (boolean, default is false):
If true, using redefined computation for sqrt(double),
else it delegates to StrictMath.sqrt(double).
False by default because StrictMath.sqrt(double) seems usually fast.