public final class MathOps
extends java.lang.Object
The following is the mapping of Progress language features to the corresponding feature in this class:
+ operatorplus(NumberType,NumberType)
+ operatorplus(int64,int64)
- operatorminus(NumberType,NumberType)
- operatorminus(int64,int64)
- operator (unary minus)negate(decimal)
- operator (unary minus)negate(int64)
* operatormultiply(NumberType,NumberType)
* operatormultiply(int64,int64)
/ operatordivide(NumberType,NumberType)
MODULO operatormodulo(NumberType,NumberType)
absolute functionabs(decimal)
absolute functionabs(int64)
log functionlog(NumberType,NumberType)
exp functionpow(NumberType,NumberType)
random functionrandom(int64,int64)
round functionround(decimal,int64)
sqrt functionsqrt(NumberType)
truncate functiontruncate(decimal,int64)
The above methods all return an instance of decimal
or int64
which allows the
Progress unknown value to be properly handled. Overloaded versions of the operator and
function methods exist which handle different combinations of primitive type parameters,
allowing the resulting code to be implemented without constant construction of
the wrapper types for all parameters.
The return value for the above functions are usually determined by their parameters. Usually,
if there is at least one of decimal type, the result is of decimal type. The exceptions are
modulo
and random
, for which the arguments are first rounded to
their integer value and then the operation take place returning an integer and divide that
will always return a decimal.
As integer
class is derived from int64
, the above operations which
have integer
parameters will also work on integer
arguments.
Note:
Progress documentation that mention that if both argument of an operation are
integer
the result will also be integer
.
We have found no evidence of that and we cannot find any way to actually prove that the 4GL
will emit integer in practice. In all our testcases any 32-bit overflow will silently yield
an int64 and we cannot find any use case where integer is required and int64 makes things fail.
Even the -noint64
mode has no effect on the return type 4GL built-in functions,
they can return values not representable on 32 bits.
This class implements unknown value logic for all operators and functions. Generally, if any parameter of the these methods is unknown, the result is unknown.
Modifier and Type | Field and Description |
---|---|
private static java.math.MathContext |
EXP_MCONTEXT
Math context used by the exponentiation algorithm.
|
private static java.util.Random |
generator
Cached random number generator.
|
private static java.math.BigDecimal |
LOG_10
Natural logarithm of 10.
|
private static int |
LOG_ITERATIONS
The length of the hyperbolic tangent function series used for the log implementation.
|
private static int |
LOG_PRECISION
The internal precision of the log implementation derived from decimal.MAX_SCALE.
|
private static double |
MAX_SAFE
Largest mantissa that can be safely represented without digit loss.
|
private static int |
SQRT_MAX_ITERATIONS
The maximum number of iterations for the converging SQRT algorithm.
|
Constructor and Description |
---|
MathOps() |
Modifier and Type | Method and Description |
---|---|
static decimal |
abs(decimal d)
Return the absolute value of the passed numeric parameter.
|
static decimal |
abs(double d)
Return the absolute value of the passed numeric parameter.
|
static int64 |
abs(int64 i)
Return the absolute value of the passed numeric parameter.
|
static int64 |
abs(long i)
Return the absolute value of the passed numeric parameter.
|
static decimal |
divide(BaseDataType op1,
double op2)
Hack! Temporarily.
|
static decimal |
divide(double op1,
double op2)
Implements the binary floating-point division arithmetic operator to
divide the left operand by the right operand and return the result.
|
static decimal |
divide(double op1,
NumberType op2)
Implements the binary floating-point division arithmetic operator to
divide the left operand by the right operand and return the result.
|
static decimal |
divide(NumberType op1,
double op2)
Implements the binary floating-point division arithmetic operator to
divide the left operand by the right operand and return the result.
|
static decimal |
divide(NumberType op1,
NumberType op2)
Implements the binary floating-point division arithmetic operator to
divide the left operand by the right operand and return the result.
|
private static java.math.BigDecimal |
exp(java.math.BigDecimal exponent)
Raise e (Euler's number) to the power of the second number (the
exponent).
|
private static java.math.BigDecimal |
expTaylorSeries(java.math.BigDecimal exponent)
Raise e (Euler's number) to the power of the second number (the
exponent).
|
private static void |
genModuloError(long op2)
Generate an error if the 2nd operand to
modulo(com.goldencode.p2j.util.NumberType, com.goldencode.p2j.util.NumberType) is not positive. |
private static java.math.BigDecimal |
log(java.math.BigDecimal num)
Calculate the natural logarithm of a number.
|
private static java.math.BigDecimal |
log(java.math.BigDecimal num,
java.math.BigDecimal base)
Calculate the logarithm of a number in a specific base.
|
static decimal |
log(double num)
Calculate the natural logarithm of a number (base e).
|
static decimal |
log(double num,
double base)
Calculate the logarithm of a number in a specific base.
|
static decimal |
log(NumberType num)
Calculate the natural logarithm of a number (base e).
|
static decimal |
log(NumberType num,
double base)
Calculate the logarithm of a number in a specific base.
|
static decimal |
log(NumberType num,
int base)
Calculate the logarithm of a number in a specific base.
|
static decimal |
log(NumberType num,
NumberType base)
Calculate the logarithm of a number in a specific base.
|
static decimal |
minus(double op1,
double op2)
Implements the binary minus arithmetic operator to subtract the
right operand from the left and return the result.
|
static decimal |
minus(double op1,
NumberType op2)
Implements the binary minus arithmetic operator to subtract the
right operand from the left and return the result.
|
static int64 |
minus(int64 op1,
int64 op2)
Implements the binary minus arithmetic operator to subtract the
right operand from the left and return the result.
|
static int64 |
minus(int64 op1,
long op2)
Implements the binary minus arithmetic operator to subtract the
right operand from the left and return the result.
|
static int64 |
minus(long op1,
int64 op2)
Implements the binary minus arithmetic operator to subtract the
right operand from the left and return the result.
|
static int64 |
minus(long op1,
long op2)
Implements the binary minus arithmetic operator to subtract the
right operand from the left and return the result.
|
static decimal |
minus(NumberType op1,
double op2)
Implements the binary minus arithmetic operator to subtract the
right operand from the left and return the result.
|
static decimal |
minus(NumberType op1,
NumberType op2)
Implements the binary minus arithmetic operator to subtract the
right operand from the left and return the result.
|
static int64 |
modulo(double op1,
double op2)
Implements the binary modulo (remainder) arithmetic operator which divides the left operand
by the right operand (the base) and returns the resulting integral remainder.
|
static int64 |
modulo(double op1,
NumberType op2)
Implements the binary modulo (remainder) arithmetic operator which
divides the left operand by the right operand (the base) and returns
the resulting integral remainder.
|
static int64 |
modulo(long op1,
long op2)
Implements the binary modulo (remainder) arithmetic operator which divides the left operand
by the right operand (the base) and returns the resulting integral remainder.
|
static int64 |
modulo(long op1,
NumberType op2)
Implements the binary modulo (remainder) arithmetic operator which
divides the left operand by the right operand (the base) and returns
the resulting integral remainder.
|
static int64 |
modulo(NumberType op1,
double op2)
Implements the binary modulo (remainder) arithmetic operator which
divides the left operand by the right operand (the base) and returns
the resulting integral remainder.
|
static int64 |
modulo(NumberType op1,
long op2)
Implements the binary modulo (remainder) arithmetic operator which
divides the left operand by the right operand (the base) and returns
the resulting integral remainder.
|
static int64 |
modulo(NumberType op1,
NumberType op2)
Implements the binary modulo (remainder) arithmetic operator which divides the left operand
by the right operand (the base) and returns the resulting integral remainder.
|
static decimal |
multiply(double op1,
double op2)
Implements the binary multiply arithmetic operator to multiply the
two operands and return the result.
|
static decimal |
multiply(double op1,
NumberType op2)
Implements the binary multiply arithmetic operator to multiply the
two operands and return the result.
|
static int64 |
multiply(int64 op1,
int64 op2)
Implements the binary multiply arithmetic operator to multiply the
two operands and return the result.
|
static int64 |
multiply(int64 op1,
long op2)
Implements the binary multiply arithmetic operator to multiply the
two operands and return the result.
|
static int64 |
multiply(long op1,
int64 op2)
Implements the binary multiply arithmetic operator to multiply the
two operands and return the result.
|
static int64 |
multiply(long op1,
long op2)
Implements the binary multiply arithmetic operator to multiply the
two operands and return the result.
|
static decimal |
multiply(NumberType op1,
double op2)
Implements the binary multiply arithmetic operator to multiply the
two operands and return the result.
|
static decimal |
multiply(NumberType op1,
NumberType op2)
Implements the binary multiply arithmetic operator to multiply the
two operands and return the result.
|
static decimal |
negate(decimal d)
Implements the unary minus operator for the
decimal type. |
static decimal |
negate(double d)
Implements the unary minus operator.
|
static int64 |
negate(int64 i)
Implements the unary minus operator for the
integer type. |
static int64 |
negate(long i)
Implements the unary minus operator.
|
static decimal |
plus(double op1,
double op2)
Implements the binary plus arithmetic operator to add the right
operand to the left and return the result.
|
static decimal |
plus(double op1,
NumberType op2)
Implements the binary plus arithmetic operator to add the right
operand to the left and return the result.
|
static int64 |
plus(int64 op1,
int64 op2)
Implements the binary plus arithmetic operator to add the right
operand to the left and return the result.
|
static int64 |
plus(int64 op1,
long op2)
Implements the binary plus arithmetic operator to add the right
operand to the left and return the result.
|
static int64 |
plus(long op1,
int64 op2)
Implements the binary plus arithmetic operator to add the right
operand to the left and return the result.
|
static int64 |
plus(long op1,
long op2)
Implements the binary plus arithmetic operator to add the right
operand to the left and return the result.
|
static decimal |
plus(NumberType op1,
double op2)
Implements the binary plus arithmetic operator to add the right
operand to the left and return the result.
|
static decimal |
plus(NumberType op1,
NumberType op2)
Implements the binary plus arithmetic operator to add the right
operand to the left and return the result.
|
private static java.math.BigDecimal |
pow(java.math.BigDecimal base,
java.math.BigDecimal exponent)
Raise one number (the base) to the power of the second number (the
exponent).
|
static decimal |
pow(double base,
double exponent)
Raise one number (the base) to the power of the second number (the
exponent).
|
static decimal |
pow(double base,
NumberType exponent)
Raise one number (the base) to the power of the second number (the
exponent).
|
static decimal |
pow(NumberType base,
double exponent)
Raise one number (the base) to the power of the second number (the
exponent).
|
static decimal |
pow(NumberType base,
NumberType exponent)
Raise one number (the base) to the power of the second number (the exponent).
|
static int64 |
random(double low,
double high)
Generate a psuedo-randomly distributed number between the low and high values inclusively.
|
static int64 |
random(double low,
NumberType high)
Generate a psuedo-randomly distributed number between the low and high values inclusively.
|
static int64 |
random(int64 low,
int64 high)
Generate a psuedo-randomly distributed number between the low and
high values inclusively.
|
static int64 |
random(int64 low,
long high)
Generate a psuedo-randomly distributed number between the low and
high values inclusively.
|
static int64 |
random(long low,
int64 high)
Generate a psuedo-randomly distributed number between the low and
high values inclusively.
|
static int64 |
random(long low,
long high)
Generate a psuedo-randomly distributed number between the low and
high values inclusively.
|
static int64 |
random(NumberType low,
double high)
Generate a psuedo-randomly distributed number between the low and high values inclusively.
|
static int64 |
random(NumberType low,
NumberType high)
Generate a psuedo-randomly distributed number between the low and high values inclusively.
|
static java.math.BigDecimal |
round(java.math.BigDecimal value)
Rounds the given decimal value to 10 digits of precision to the right
side of the decimal point.
|
static java.math.BigDecimal |
round(java.math.BigDecimal value,
int precision)
Rounds the given decimal value to the user-specified number of digits
of precision to the right side of the decimal point.
|
private static java.math.BigDecimal |
round(java.math.BigDecimal value,
int precision,
int roundingMode)
Rounds the given decimal value to the user-specified number of digits
of precision to the right side of the decimal point, using the given
rounding mode.
|
static decimal |
round(decimal value)
Rounds the passed
decimal to 10 digits of precision to the
right side of the decimal point. |
static decimal |
round(decimal value,
int precision)
Rounds the passed
decimal to the user-specified number of
digits of precision to the right side of the decimal point. |
static decimal |
round(decimal value,
int64 precision)
Rounds the passed
decimal to the user-specified number of
digits of precision to the right side of the decimal point. |
static double |
round(double value)
Rounds the passed
double to 10 digits of precision to the
right side of the decimal point. |
static double |
round(double value,
int precision)
Rounds the passed
double to the user-specified number of
digits of precision to the right side of the decimal point. |
private static java.math.BigDecimal |
sqrt(java.math.BigDecimal num)
Calculate the square root of a number.
|
static decimal |
sqrt(double num)
Calculate the square root of a number.
|
static decimal |
sqrt(NumberType num)
Calculate the square root of a number.
|
static java.math.BigDecimal |
truncate(java.math.BigDecimal value,
int precision)
Truncates the passed
BigDecimal to the specified number
of digits of precision to the right side of the decimal point. |
static decimal |
truncate(decimal value,
int precision)
Truncates the passed
decimal to the user-specified number
of digits of precision to the right side of the decimal point. |
static decimal |
truncate(decimal value,
int64 precision)
Truncates the passed
decimal to the user-specified number
of digits of precision to the right side of the decimal point. |
static double |
truncate(double value,
int precision)
Truncates the passed
double to the user-specified number
of digits of precision to the right side of the decimal point. |
private static double |
truncateWorker(double value,
int precision,
boolean round)
Core logic to round or truncate a passed
double to the
user-specified precision (number of digits to the right of the
decimal point). |
private static final double MAX_SAFE
private static final int SQRT_MAX_ITERATIONS
private static final java.math.BigDecimal LOG_10
private static final int LOG_ITERATIONS
private static final int LOG_PRECISION
private static final java.math.MathContext EXP_MCONTEXT
private static java.util.Random generator
Note: this is safe (and actually it is preferred) to be JVM-wide (static) rather than a context-local instance. This is true since any use of this from multiple threads will have a much more random result than if the usage was only on one thread.
public static decimal abs(decimal d)
d
- The number on which to take the absolute value.unknown value
when the input is the unknown value
.public static decimal abs(double d)
d
- The number on which to take the absolute value.public static int64 abs(int64 i)
i
- The number on which to take the absolute value.unknown value
when the input is the unknown value
.public static int64 abs(long i)
i
- The number on which to take the absolute value.public static decimal log(NumberType num)
num
- The number for which the logarithm should be computed.unknown value
when input is the
unknown
value or not strictly positive.public static decimal log(NumberType num, NumberType base)
num
- The number for which the logarithm should be computed.base
- The logarithm base.unknown
value when any input is null
value or when base
is not strictly positive or 1 or when num
is not strictly positive.public static decimal log(NumberType num, double base)
num
- The number for which the logarithm should be computed.base
- The logarithm base.unknown
value when any input is null
value or when base
is not strictly positive or 1 or when num
is not strictly positive.public static decimal log(NumberType num, int base)
num
- The number for which the logarithm should be computed.base
- The logarithm base.unknown
value when any input is null
value or when base
is not strictly positive or 1 or when num
is not strictly positive.public static decimal log(double num, double base)
num
- The number for which the logarithm should be computed.base
- The logarithm base.unknown
value when any input is null
value or when base
is not strictly positive or 1 or when num
is not strictly positive.public static decimal log(double num)
num
- The number for which the logarithm should be computed.public static decimal pow(NumberType base, NumberType exponent)
base
- The number to be exponentiated.exponent
- The power to which the number should be raised.unknown value
when either input is the
unknown value
.public static decimal pow(double base, NumberType exponent)
base
- The number to be exponentiated.exponent
- The power to which the number should be raised.unknown value
when either input is the unknown value
.public static decimal pow(NumberType base, double exponent)
base
- The number to be exponentiated.exponent
- The power to which the number should be raised.unknown value
when either input is the unknown value
.public static decimal pow(double base, double exponent)
base
- The number to be exponentiated.exponent
- The power to which the number should be raised.public static int64 random(long low, int64 high)
low
- The bottom end of the range (inclusive).high
- The top end of the range (inclusive).public static int64 random(int64 low, long high)
low
- The bottom end of the range (inclusive).high
- The top end of the range (inclusive).public static int64 random(int64 low, int64 high)
low
- The bottom end of the range (inclusive).high
- The top end of the range (inclusive).public static int64 random(long low, long high)
low
- The bottom end of the range (inclusive).high
- The top end of the range (inclusive).public static int64 random(NumberType low, NumberType high)
low
- The bottom end of the range (inclusive).high
- The top end of the range (inclusive).public static int64 random(double low, NumberType high)
low
- The bottom end of the range (inclusive).high
- The top end of the range (inclusive).public static int64 random(NumberType low, double high)
low
- The bottom end of the range (inclusive).high
- The top end of the range (inclusive).public static int64 random(double low, double high)
low
- The bottom end of the range (inclusive).high
- The top end of the range (inclusive).public static decimal sqrt(NumberType num)
num
- The number for which to obtain the square root.unknown value
when input is negative.public static decimal sqrt(double num)
num
- The number for which to obtain the square root.unknown value
when input is negative.private static java.math.BigDecimal sqrt(java.math.BigDecimal num)
When null is returned, it should be interpreted as an unknown value back to the converted code.
Precision-wise this method yields comparable outputs up to the inputs
of 10^15. See the table below showing error magnitudes of several exemplary
inputs comparing Progress native sqrt (version 10.2B) and this method.
Input: 10^11 10^13 10^15 10^17 10^41
Progress Error: 0.0000209975 0.0010625323 0.2415973135 28.5870600263 6385341029806439311343616
P2J Error: 0.0000422480 0.0004300767 0.0026421128 0.00006997839 17801490614.8294175592
num
- The number for which to obtain the square root.null
if the input value is null
or negative.public static decimal round(decimal value, int64 precision)
decimal
to the user-specified number of
digits of precision to the right side of the decimal point. If the
precision is specified as X then the X+1th digit is 5 or more, the
Xth digit is increased by 1, otherwise it is left alone. All digits
after the Xth are then dropped/truncated. The specified precision
must be non-negative and any value greater than 10 is forced to 10.
If this instance represents the unknown value
, the
result will be the unknown value
.
value
- The number to round.precision
- The number of digits of precision to support.decimal
result.public static decimal round(decimal value, int precision)
decimal
to the user-specified number of
digits of precision to the right side of the decimal point. If the
precision is specified as X then the X+1th digit is 5 or more, the
Xth digit is increased by 1, otherwise it is left alone. All digits
after the Xth are then dropped/truncated. The specified precision
must be non-negative and any value greater than 10 is forced to 10.
If this instance represents the unknown value
, the
result will be the unknown value
.
value
- The number to round.precision
- The number of digits of precision to support.decimal
result.public static decimal round(decimal value)
decimal
to 10 digits of precision to the
right side of the decimal point. If the 11th digit is 5 or more, the
10th digit is increased by 1, otherwise it is left alone. All digits
after the 10th are then dropped/truncated.
If this instance represents the unknown value
, the
result will be the unknown value
.
value
- The number to round.decimal
result.public static double round(double value, int precision)
double
to the user-specified number of
digits of precision to the right side of the decimal point. If the
precision is specified as X then the X+1th digit is 5 or more, the
Xth digit is increased by 1, otherwise it is left alone. All digits
after the Xth are then dropped/truncated. The specified precision
must be non-negative and any value greater than 10 is forced to 10.
If the value is NaN
the resulting double
will
be set to NaN
.
value
- The number to round.precision
- The number of digits of precision to support.double
result.public static java.math.BigDecimal round(java.math.BigDecimal value, int precision)
If the value is null
, null
is returned. If
precision is negative, 0 is returned.
value
- The number to round.precision
- The number of digits of precision to support.decimal
result.public static java.math.BigDecimal round(java.math.BigDecimal value)
If the value is null
, null
is returned.
value
- The number to round.decimal
result.public static double round(double value)
double
to 10 digits of precision to the
right side of the decimal point. If the 11th digit is 5 or more, the
10th digit is increased by 1, otherwise it is left alone. All digits
after the 10th are then dropped/truncated.
If the value is NaN
the resulting double
will
be set to NaN
.
value
- The number to round.double
result.public static decimal truncate(decimal value, int64 precision)
decimal
to the user-specified number
of digits of precision to the right side of the decimal point. The
specified precision must be non-negative and any value greater than 10
is forced to 10.
If this instance represents the unknown value
, the
result will be the unknown value
.
value
- The number to truncate.precision
- The number of digits of precision to support.decimal
result.public static decimal truncate(decimal value, int precision)
decimal
to the user-specified number
of digits of precision to the right side of the decimal point. The
specified precision must be non-negative and any value greater than 10
is forced to 10.
If this instance represents the unknown value
, the
result will be the unknown value
.
value
- The number to truncate.precision
- The number of digits of precision to support.decimal
result.public static java.math.BigDecimal truncate(java.math.BigDecimal value, int precision)
BigDecimal
to the specified number
of digits of precision to the right side of the decimal point. The
specified precision must be non-negative and any value greater than 10
is forced to 10.
If the value is null
, then null
is returned.
value
- The number to truncate.precision
- The number of digits of precision to support.BigDecimal
result.public static double truncate(double value, int precision)
double
to the user-specified number
of digits of precision to the right side of the decimal point. The
specified precision must be non-negative and any value greater than 10
is forced to 10.
If the value is NaN
the resulting double
will
be set to NaN
.
value
- The number to truncate.precision
- The number of digits of precision to support.double
result.public static decimal negate(decimal d)
decimal
type.
If the operand is the unknown value
, the result will
be the unknown value
.
d
- The decimal
to negate.public static decimal negate(double d)
d
- The number to negate.public static int64 negate(int64 i)
integer
type.
If the operand is the unknown value
, the result will
be the unknown value
.
i
- The integer
to negate.public static int64 negate(long i)
i
- The number to negate.public static decimal plus(NumberType op1, NumberType op2)
If either operand is the unknown value
, the result will
be the unknown value
.
op1
- The left operand.op2
- The right operand.public static decimal plus(double op1, NumberType op2)
If the second operand is the unknown value
, the result
will be the unknown value
.
op1
- The left operand.op2
- The right operand.public static decimal plus(NumberType op1, double op2)
If the first operand is the unknown value
, the result will
be the unknown value
.
op1
- The left operand.op2
- The right operand.public static decimal plus(double op1, double op2)
op1
- The left operand.op2
- The right operand.public static int64 plus(int64 op1, int64 op2)
If either operand is the unknown value
, the result will
be the unknown value
.
op1
- The left operand.op2
- The right operand.public static int64 plus(int64 op1, long op2)
If the first operand is the unknown value
, the result will
be the unknown value
.
op1
- The left operand.op2
- The right operand.public static int64 plus(long op1, int64 op2)
If the second operand is the unknown value
, the result
will be the unknown value
.
op1
- The left operand.op2
- The right operand.public static int64 plus(long op1, long op2)
op1
- The left operand.op2
- The right operand.public static decimal minus(NumberType op1, NumberType op2)
If either operand is the unknown value
, the result will
be the unknown value
.
op1
- The left operand.op2
- The right operand.public static decimal minus(double op1, NumberType op2)
If the second operand is the unknown value
, the result
will be the unknown value
.
op1
- The left operand.op2
- The right operand.public static decimal minus(NumberType op1, double op2)
If the first operand is the unknown value
, the result will
be the unknown value
.
op1
- The left operand.op2
- The right operand.public static decimal minus(double op1, double op2)
op1
- The left operand.op2
- The right operand.public static int64 minus(int64 op1, int64 op2)
If either operand is the unknown value
, the result will
be the unknown value
.
op1
- The left operand.op2
- The right operand.public static int64 minus(long op1, int64 op2)
If the second operand is the unknown value
, the result
will be the unknown value
.
op1
- The left operand.op2
- The right operand.public static int64 minus(int64 op1, long op2)
If the first operand is the unknown value
, the result will
be the unknown value
.
op1
- The left operand.op2
- The right operand.public static int64 minus(long op1, long op2)
op1
- The left operand.op2
- The right operand.public static decimal multiply(NumberType op1, NumberType op2)
If either operand is the unknown value
, the result will
be the unknown value
.
op1
- The left operand.op2
- The right operand.public static decimal multiply(double op1, NumberType op2)
If the second operand is the unknown value
, the result
will be the unknown value
.
op1
- The left operand.op2
- The right operand.public static decimal multiply(NumberType op1, double op2)
If the first operand is the unknown value
, the result will
be the unknown value
.
op1
- The left operand.op2
- The right operand.public static decimal multiply(double op1, double op2)
op1
- The left operand.op2
- The right operand.public static int64 multiply(int64 op1, int64 op2)
If either operand is the unknown value
, the result will
be the unknown value
.
op1
- The left operand.op2
- The right operand.public static int64 multiply(long op1, long op2)
If either operand is the unknown value
, the result will
be the unknown value
.
op1
- The left operand.op2
- The right operand.public static int64 multiply(int64 op1, long op2)
If either operand is the unknown value
, the result will
be the unknown value
.
op1
- The left operand.op2
- The right operand.public static int64 multiply(long op1, int64 op2)
If either operand is the unknown value
, the result will
be the unknown value
.
op1
- The left operand.op2
- The right operand.public static decimal divide(NumberType op1, NumberType op2)
truncate(com.goldencode.p2j.util.decimal, com.goldencode.p2j.util.int64)
on the result if this is necessary).
If either operand is the unknown value
, the result will
be the unknown value
. In addition, division by 0 will
silently result in the unknown value
.
op1
- The left operand.op2
- The right operand.public static decimal divide(double op1, NumberType op2)
truncate(com.goldencode.p2j.util.decimal, com.goldencode.p2j.util.int64)
on the result if this is necessary).
If the second operand is the unknown value
, the result will
be the unknown value
. In addition, division by 0 will
silently result in the unknown value
.
op1
- The left operand.op2
- The right operand.public static decimal divide(NumberType op1, double op2)
truncate(com.goldencode.p2j.util.decimal, com.goldencode.p2j.util.int64)
on the result if this is necessary).
If the first operand is the unknown value
, the result will
be the unknown value
. In addition, division by 0 will
silently result in the unknown value
.
op1
- The left operand.op2
- The right operand.public static decimal divide(double op1, double op2)
truncate(com.goldencode.p2j.util.decimal, com.goldencode.p2j.util.int64)
on the result if this is necessary).
Division by 0 will silently result in the unknown value
.
op1
- The left operand.op2
- The right operand.public static decimal divide(BaseDataType op1, double op2)
op1
- The left operand.op2
- The right operand.public static int64 modulo(NumberType op1, NumberType op2)
If any of the operands are not integer type, they are first rounded to the closest long and then the operation is performed using usual arithmetic. After rounding, the base must be positive (> 0).
If either operand is the unknown value
, the result will
be the unknown value
.
op1
- The left operand (number to divide).op2
- The right operand (the divisor or modulo base).public static int64 modulo(double op1, NumberType op2)
If the second operand is the unknown value
, the result
will be the unknown value
.
op1
- The left operand (number to divide).op2
- The right operand (the divisor or modulo base).public static int64 modulo(NumberType op1, double op2)
If the first operand is the unknown value
, the result will
be the unknown value
.
op1
- The left operand (number to divide).op2
- The right operand (the divisor or modulo base).public static int64 modulo(long op1, NumberType op2)
If the first operand is the unknown value
, the result will
be the unknown value
.
op1
- The left operand (number to divide).op2
- The right operand (the divisor or modulo base).public static int64 modulo(NumberType op1, long op2)
If the first operand is the unknown value
, the result will
be the unknown value
.
op1
- The left operand (number to divide).op2
- The right operand (the divisor or modulo base).public static int64 modulo(double op1, double op2)
If one or both operands are not integers, they are first rounded to an integer value and then the operation is carried using integer arithmetics. The rounding must fit in 64-bit space or
If the left operand is greater than zero, then the result will be as expected from normal integral arithmetic (the remainder after integer division will be returned). However, if the left operand is not greater than zero, then the result will depend on the value of the remainder after the absolute value of the left operand is integrally divided into the base. Zero will be returned if the remainder in this case is zero, otherwise the base minus the remainder will be returned. Warning: the Progress documentation only suggests that this is an invalid case which should not be relied upon. However, client application code has been found to be reliant upon this behavior.
op1
- The left operand (number to divide).op2
- The right operand (the divisor or modulo base).public static int64 modulo(long op1, long op2)
If the left operand is greater than zero, then the result will be as expected from normal integral arithmetic (the remainder after integer division will be returned). However, if the left operand is not greater than zero, then the result will depend on the value of the remainder after the absolute value of the left operand is integrally divided into the base. Zero will be returned if the remainder in this case is zero, otherwise the base minus the remainder will be returned. Warning: the Progress documentation only suggests that this is an invalid case which should not be relied upon. However, client application code has been found to be reliant upon this behavior.
op1
- The left operand (number to divide).op2
- The right operand (the divisor or modulo base).private static java.math.BigDecimal round(java.math.BigDecimal value, int precision, int roundingMode)
For rounding mode BigDecimal.ROUND_HALF_UP
: If the
precision is specified as X and the X+1th digit is 5 or more, the Xth
digit is increased by 1, otherwise it is left alone. All digits after
the Xth are then dropped/truncated.
For rounding mode BigDecimal.ROUND_DOWN
: If the precision
is specified as X then all digits after the Xth are dropped/truncated.
The specified precision must be non-negative and any value greater than 10 is forced to 10.
If the value is null
, null
is returned. If
precision is negative, 0 is returned.
value
- The number to round.precision
- The number of digits of precision to support.roundingMode
- Either BigDecimal.ROUND_HALF_UP
(to round) or
BigDecimal.ROUND_DOWN
(to truncate).double
result.private static double truncateWorker(double value, int precision, boolean round) throws java.lang.IllegalArgumentException
double
to the
user-specified precision (number of digits to the right of the
decimal point). If round
is true
and if the
precision is specified as X then when the X+1th digit is 5 or more, the
Xth digit is increased by 1, otherwise it is left alone. All digits
after the Xth are then dropped/truncated. If round
is
false
then the Xth digit is always unchanged and all
digits greater than X are truncated. The specified precision
must be non-negative and any value greater than 10 is forced to 10.
The algorithm used relies upon scaling (multiplying) the input value
by a power of 10 based on the precision (for example, by
Math.pow(10, precision)
). This leaves all digits to be
kept in the result, to the left of the decimal point. Then this
double
is cast to a long
(truncate mode)
or rounded into a long
(round mode) which drops the
extra digits. Finally, the value is de-scaled (divided by) the same
scaling value to obtain a properly scaled result.
This algorithm will fail when used on large numbers (positive or
negative) with large precision. This is due to the fact that the
intermediate resulting double
(after scaling) can be larger
than Long.MAX_VALUE
or smaller than
Long.MIN_VALUE
which breaks the algorithm.
If the passed value to be rounded/truncated is NaN
, the
result will be NaN
.
value
- The value to be rounded or truncated.precision
- The number of significant digits to maintain to the right of
the decimal point. Use 0 to get a value that is integral.round
- true
to using rounding, false
to
obtain truncation.java.lang.IllegalArgumentException
- If the intermediate result is too large or too small to fit
into a long
(e.g. positive or negative
infinity) or if the precision is negative.private static void genModuloError(long op2)
modulo(com.goldencode.p2j.util.NumberType, com.goldencode.p2j.util.NumberType)
is not positive.op2
- The second parameter (provided for insertion into the error message.private static java.math.BigDecimal log(java.math.BigDecimal num, java.math.BigDecimal base)
num
- The number for which the logarithm should be computed.base
- The logarithm base.null
value when any input is null
value or when base
is not strictly positive or 1 or when num
is not strictly positive. Precision of the result is rounded-up to
decimal.MAX_SCALE number of decimal places.private static java.math.BigDecimal log(java.math.BigDecimal num)
num
- The number for which the logarithm should be computed.null
when the input is
null
or when num
is not strictly positive.
Precision of the result may be higher than decimal.MAX_SCALE,
it's the caller's responsibility to round down if required.private static java.math.BigDecimal pow(java.math.BigDecimal base, java.math.BigDecimal exponent)
When base is equal or less than zero and exponent is less than zero, error 9384 is raised.
When the exponent has no decimal component the method returns result
of BigDecimal.pow(int, java.math.MathContext)
, otherwise the
result of the method call pow(BigDecimal, BigDecimal)
is returned.
base
- The number to be exponentiated.exponent
- The power to which the number should be raised.null
when either input is null
.private static java.math.BigDecimal exp(java.math.BigDecimal exponent)
The method exponentiates with the help of Taylor series,
see expTaylorSeries(BigDecimal)
.
exponent
- The power to which the number should be raised.null
when the input is null
.private static java.math.BigDecimal expTaylorSeries(java.math.BigDecimal exponent)
Do not call the method directly. This method is used only by
exp(BigDecimal)
.
exponent
- The power to which the number should be raised.
Must be a valid exponent - a positive decimal number
with nonzero decimal component.