Release 2.3.0
API changes
No API changes.
Bugfixes
No Bugfix changes.
Enhancements
Added DefaultBigDecimalMath.createLocalMathContext()
and withLocalMathContext()
The class DefaultBigDecimalMath
is a wrapper around BigDecimalMath
that passes always the current MathContext
to the
functions that need a MathContext
argument.
The initial default MathContext
is equivalent to MathContext.DECIMAL128
but this can be overridden by setting the following system properties:
ch.obermuhlner.math.big.default.precision
to a positive integer precision (default=34)ch.obermuhlner.math.big.default.rounding
to a RoundingMode name (default=HALF_UP)
It is also possible to programmatically set the default MathContext
using setDefaultMathContext(MathContext)
.
It is recommended to set the desired precision in the MathContext
very early in the startup of the application and to not change it afterwards.
Important: Avoid the pitfall of setting the precision temporarily using setDefaultMathContext(MathContext)
for a calculation.
This can lead to race conditions and calculations with the wrong precision if other threads in your application do the same thing.
To set a temporary MathContext
you have to choice to use either:
DefaultBigDecimalMath.createLocalMathContext()
in a try-with-resources statementDefaultBigDecimalMath.withLocalMathContext()
with a lambda function
Example code using DefaultBigDecimalMath.createLocalMathContext()
:
System.out.println("Pi[default]: " + DefaultBigDecimalMath.pi());
try (DefaultBigDecimalMath.LocalMathContext context = DefaultBigDecimalMath.createLocalMathContext(5)) {
System.out.println("Pi[5]: " + DefaultBigDecimalMath.pi());
try (DefaultBigDecimalMath.LocalMathContext context2 = DefaultBigDecimalMath.createLocalMathContext(10)) {
System.out.println("Pi[10]: " + DefaultBigDecimalMath.pi());
};
System.out.println("Pi[5]: " + DefaultBigDecimalMath.pi());
};
System.out.println("Pi[default]: " + DefaultBigDecimalMath.pi());
Example code using DefaultBigDecimalMath.withLocalMathContext()
:
System.out.println("Pi[default]: " + DefaultBigDecimalMath.pi());
DefaultBigDecimalMath.withLocalMathContext(5, () -> {
System.out.println("Pi[5]: " + DefaultBigDecimalMath.pi());
DefaultBigDecimalMath.withLocalMathContext(10, () -> {
System.out.println("Pi[10]: " + DefaultBigDecimalMath.pi());
});
System.out.println("Pi[5]: " + DefaultBigDecimalMath.pi());
});
System.out.println("Pi[default]: " + DefaultBigDecimalMath.pi());
Both snippets will give the following output:
Pi[default]: 3.141592653589793238462643383279503
Pi[5]: 3.1416
Pi[10]: 3.141592654
Pi[5]: 3.1416
Pi[default]: 3.141592653589793238462643383279503
The temporary MathContext
are stored in ThreadLocal
variables
and will therefore not conflict with each other when used in multi-threaded use case.
Important: Due to the ThreadLocal
variables the temporary MathContext
will
not be available in other threads.
This includes streams using parallel()
, thread pools and manually started threads.
If you need temporary MathContext
for calculations then you must
set the local MathContext
inside every separate thread.
try (DefaultBigDecimalMath.LocalMathContext context = DefaultBigDecimalMath.createLocalMathContext(5)) {
BigDecimalStream.range(0.0, 1.0, 0.01, DefaultBigDecimalMath.currentMathContext())
.map(b -> DefaultBigDecimalMath.cos(b))
.map(b -> "sequential " + Thread.currentThread().getName() + " [5]: " + b)
.forEach(System.out::println);
BigDecimalStream.range(0.0, 1.0, 0.01, DefaultBigDecimalMath.currentMathContext())
.parallel()
.map(b -> {
try (DefaultBigDecimalMath.LocalMathContext context2 = DefaultBigDecimalMath.createLocalMathContext(5)) {
return DefaultBigDecimalMath.cos(b);
}
})
.map(b -> "parallel " + Thread.currentThread().getName() + " [5]: " + b)
.forEach(System.out::println);
}
Examples
Note: The example code is available on github, but not part of the big-math library.
Examples for createLocalMathContext()
and withLocalMathContext()
Example code was added to the class DefaultBigDecimalMathExample
to demonstrate the usage of DefaultBigDecimalMath.createLocalMathContext()
and DefaultBigDecimalMath.withLocalMathContext()
.