Variable Math
In MAPPER, operators like +, -, and * perform math on variables in commands like @ART
,
@CHG
and @CAL
. The
MJ variable classes support similar mathematical operations and functions via
the IMathOperators
and IMathFunctions interfaces.
Only MJDecimal
,
MJInteger
and MJVariant
implement
these interfaces; while MJ
supports math involving MJString
variables,
it follows Java's strong typing by encouraging math on numbers and discouraging math on strings.
MJ also provides formulas as a convenient way to perform math with variables;
internally, formulas make use of the IMathOperators
and
IMathFunctions
interfaces.
Interface IMathOperators
Here are the binary and unary mathematical methods available in IMathOperators
:
MAPPER Operator | Description | IMathOperators Method |
---|---|---|
+ | Addition: a+b |
add |
- | Subtraction: a-b |
subtract |
/ | Division: a/b |
divide |
// | Integer division: a//b . Gives the unrounded integer portion of the dividend of
value a divided by value b . |
divideToIntegralValue |
* | Multiplication: a*b |
multiply |
** | Exponentiation: a**b . Gives the result of value a raised
to the power of value b . |
pow |
- | Unary minus: -a . Gives the negative of value a . |
negate |
The IMathOperators
interface also
supports increment and
decrement as the equivalent of MAPPER
@INC
and @DEC
.
Interface IMathFunctions
The mathematical functions supported
by @ART
and @CAL
are
available in IMathFunctions
:
MAPPER Function | Description | IMathFunctions Method |
---|---|---|
ABS (x ) |
Absolute value or magnitude of x . |
abs |
MOD (x ,y ) |
Modulus; remainder value of x /y . |
mod |
FRAC (x ) |
Fractional portion of x . |
frac |
INT (x ) |
Integer portion of x . |
intf |
SQRT (x ) |
Square root of x . |
sqrt |
Methods similar to trigonometric functions like ACOS
(x
),
DEG
(x
) and
LOG
(x
) are also
present in IMathFunctions
.
Examples of Math with MJ Numeric Variables
Here are examples of mathematical methods and functions supported by MJDecimal
and MJInteger
:
//////////////////// Addition (@CHG) ////////////////////////////////////
// @LDV <decVar>f3.2=9.428 .
// @CHG <sumVar>f7.3 <decVar> + 22 .
MJDecimal decVar = new MJDecimal(VariableScope.LOCAL, 3, 2, new BigDecimal("9.428"));
Number sum = decVar.add(22L, EnumSet.of(MathOption.EVALUATE_JAVA_TYPE));
assert sum instanceof BigDecimal;
MJDecimal sumVar = new MJDecimal(VariableScope.LOCAL, 7, 3, (BigDecimal) sum);
assert "31.428".equals(sumVar.toMapperNumericString());
//////////////////// Subtraction (@ART) /////////////////////////////////
// @LDV <sub1>f4.2=10.8765, <sub2>f4.2=-1.43 .
// @ART <sub1>-<sub2> <diffVar>f18.17 .
MJDecimal sub1 = new MJDecimal(VariableScope.LOCAL, 4, 2, new BigDecimal("10.8765"));
MJDecimal sub2 = new MJDecimal(VariableScope.LOCAL, 4, 2, new BigDecimal("-1.43"));
Number diff = sub1.subtract(sub2, EnumSet.of(MathOption.EVALUATE_MAPPER_TYPE));
assert diff instanceof BigDecimal;
MJDecimal diffVar = new MJDecimal(VariableScope.LOCAL, 18, 17, (BigDecimal) diff);
assert "12.300000000000000".equals(diffVar.toMapperNumericString());
//////////////////// Multiplication (@CHG) //////////////////////////////
// @LDV <mpc>i9=987654321, <mpi>i8=86453095 .
// @CHG <intRslt>i16 <mpc> * <mpi> .
MJInteger mpc = new MJInteger(VariableScope.LOCAL, 9,
EnumSet.noneOf(LoadOption.class), "987654321");
MJInteger mpi = new MJInteger(VariableScope.LOCAL, 8,
EnumSet.noneOf(LoadOption.class), "86453095");
Number prod = mpc.multiply(mpi, EnumSet.of(MathOption.EVALUATE_JAVA_TYPE));
assert prod instanceof Long;
MJInteger intRslt = new MJInteger(VariableScope.LOCAL, 16, ((Long) prod).longValue());
assert "8.53857728406E16".equals(intRslt.toMapperNumericString());
//////////////////// Division (@CHG) ////////////////////////////////////
// @LDV <dvd>i4=22, <dvi>i4=7 .
// @CHG <fltPi>f18.17 <dvd> / <dvi> .
MJInteger dvd = new MJInteger(VariableScope.LOCAL, 4,
EnumSet.noneOf(LoadOption.class), "22");
MJInteger dvi = new MJInteger(VariableScope.LOCAL, 4,
EnumSet.noneOf(LoadOption.class), "7");
Number quot = dvd.divide(dvi, EnumSet.of(MathOption.EVALUATE_JAVA_TYPE,
MathOption.PREFER_DECIMAL_OVER_FLOAT));
assert quot instanceof BigDecimal;
MJDecimal fltPi = new MJDecimal(VariableScope.LOCAL, 18, 17, (BigDecimal) quot);
assert "3.1428571428571400".equals(fltPi.toMapperNumericString());
//////////////////// Integer Division (@CHG) ////////////////////////////
// @LDV <dvd>i4=22, <dvi>i4=7 .
// @CHG <fltPi>f18.17 <dvd> // <dvi> .
Number iq = dvd.divideToIntegralValue(dvi, EnumSet.of(MathOption.EVALUATE_JAVA_TYPE));
assert iq instanceof Long;
MJDecimal fltIQ = new MJDecimal(VariableScope.LOCAL, 18, 17,
BigDecimal.valueOf(((Long) iq).longValue(), 0));
assert "3.0000000000000000".equals(fltIQ.toMapperNumericString());
//////////////////// Exponentiation (@ART) //////////////////////////////
// @LDV <exp>i2=-2, <base>f3=-10.0 .
// @ART <base>**<exp> <fltPow>f18.17 .
MJDecimal base = new MJDecimal(VariableScope.LOCAL, 3, 0,
EnumSet.noneOf(LoadOption.class), "-10.0");
MJInteger exp = new MJInteger(VariableScope.LOCAL, 2,
EnumSet.noneOf(LoadOption.class), "-2");
Number power = base.pow(exp, EnumSet.of(MathOption.EVALUATE_MAPPER_TYPE));
assert power instanceof BigDecimal;
MJDecimal fltPow = new MJDecimal(VariableScope.LOCAL, 18, 17, (BigDecimal) power);
assert "0.0100000000000000".equals(fltPow.toMapperNumericString());
//////////////////// FRAC function (@ART) ///////////////////////////////
// @LDV <fnum>f3.2=1.23 .
// @ART FRAC(<fnum>) <fracRslt>f12.4 .
MJDecimal fnum = new MJDecimal(VariableScope.LOCAL, 3, 2,
EnumSet.noneOf(LoadOption.class), "1.23");
Number frac = fnum.frac(EnumSet.of(MathOption.EVALUATE_MAPPER_TYPE,
MathOption.PREFER_DECIMAL_OVER_FLOAT));
assert frac instanceof BigDecimal;
MJDecimal fracRslt = new MJDecimal(VariableScope.LOCAL, 12, 4, (BigDecimal) frac);
assert "0.2000".equals(fracRslt.toMapperNumericString());
//////////////////// MOD function (@ART) ///////////////////////////////
// @LDV <mdvd>f6.4=-4.4857, <mdiv>i1=2 .
// @ART MOD(<mdvd>,<mdiv>) <modRslt>f4 .
MJDecimal mdvd = new MJDecimal(VariableScope.LOCAL, 6, 4,
EnumSet.noneOf(LoadOption.class), "-4.4857");
MJInteger mdiv = new MJInteger(VariableScope.LOCAL, 4,
EnumSet.noneOf(LoadOption.class), "2");
Number mod = mdvd.mod(mdiv, EnumSet.of(MathOption.EVALUATE_MAPPER_TYPE,
MathOption.PREFER_DECIMAL_OVER_FLOAT));
assert mod instanceof BigDecimal;
MJDecimal modRslt = new MJDecimal(VariableScope.LOCAL, 4, 0, (BigDecimal) mod);
assert "-0.5".equals(modRslt.toMapperNumericString());