in java/dfp/src/main/java/com/epam/deltix/dfp/JavaImplCmp.java [242:376]
public static boolean bid64_quiet_greater(final long /*BID_UINT64*/ x, final long /*BID_UINT64*/ y) {
int exp_x, exp_y;
long /*BID_UINT64*/ sig_x, sig_y;
long /*BID_UINT128*/ sig_n_prime_w0, sig_n_prime_w1;
boolean x_is_zero = false, y_is_zero = false, non_canon_x, non_canon_y;
final boolean x_mask_sign = (x & MASK_SIGN) == MASK_SIGN;
final boolean y_mask_sign = (y & MASK_SIGN) == MASK_SIGN;
// NaN (CASE1)
// if either number is NAN, the comparison is unordered, rather than equal :
// return 0
if (((x & MASK_NAN) == MASK_NAN) || ((y & MASK_NAN) == MASK_NAN)) {
return false;
}
// SIMPLE (CASE2)
// if all the bits are the same, these numbers are equal (not Greater).
if (x == y) {
return false;
}
// INFINITY (CASE3)
if ((x & MASK_INF) == MASK_INF) {
// if x is neg infinity, there is no way it is greater than y, return 0
if ((x_mask_sign)) {
return false;
} else {
// x is pos infinity, it is greater, unless y is positive
// infinity => return y!=pos_infinity
return (((y & MASK_INF) != MASK_INF)
|| (y_mask_sign));
}
} else if ((y & MASK_INF) == MASK_INF) {
// x is finite, so if y is positive infinity, then x is less, return 0
// if y is negative infinity, then x is greater, return 1
return (y_mask_sign);
}
// if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
exp_x = (int) ((x & MASK_BINARY_EXPONENT2) >>> 51);
sig_x = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
non_canon_x = sig_x > 9999999999999999L;
} else {
exp_x = (int) ((x & MASK_BINARY_EXPONENT1) >>> 53);
sig_x = (x & MASK_BINARY_SIG1);
non_canon_x = false;
}
// if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
if ((y & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
exp_y = (int) ((y & MASK_BINARY_EXPONENT2) >>> 51);
sig_y = (y & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
non_canon_y = sig_y > 9999999999999999L;
} else {
exp_y = (int) ((y & MASK_BINARY_EXPONENT1) >>> 53);
sig_y = (y & MASK_BINARY_SIG1);
non_canon_y = false;
}
// ZERO (CASE4)
// some properties:
//(+ZERO==-ZERO) => therefore ignore the sign, and neither number is greater
//(ZERO x 10^A == ZERO x 10^B) for any valid A, B => therefore ignore the
// exponent field
// (Any non-canonical # is considered 0)
if (non_canon_x || sig_x == 0) {
x_is_zero = true;
}
if (non_canon_y || sig_y == 0) {
y_is_zero = true;
}
// if both numbers are zero, neither is greater => return NOTGREATERTHAN
if (x_is_zero && y_is_zero) {
return false;
} else if (x_is_zero) {
// is x is zero, it is greater if Y is negative
return (y_mask_sign);
} else if (y_is_zero) {
// is y is zero, X is greater if it is positive
return (!x_mask_sign);
}
// OPPOSITE SIGN (CASE5)
// now, if the sign bits differ, x is greater if y is negative
if (((x ^ y) & MASK_SIGN) == MASK_SIGN) {
return (y_mask_sign);
}
// REDUNDANT REPRESENTATIONS (CASE6)
// if both components are either bigger or smaller,
// it is clear what needs to be done
final long sig_x_unsigned = sig_x + Long.MIN_VALUE;
final long sig_y_unsigned = sig_y + Long.MIN_VALUE;
if (sig_x_unsigned > sig_y_unsigned && exp_x >= exp_y) {
return (!x_mask_sign);
}
if (sig_x_unsigned < sig_y_unsigned && exp_x <= exp_y) {
return (x_mask_sign);
}
// if exp_x is 15 greater than exp_y, no need for compensation
if (exp_x - exp_y > 15) { // difference cannot be greater than 10^15
return !x_mask_sign;// both are negative or positive
}
// if exp_x is 15 less than exp_y, no need for compensation
if (exp_y - exp_x > 15) {
return x_mask_sign; // both are negative or positive
}
// if |exp_x - exp_y| < 15, it comes down to the compensated significand
if (exp_x > exp_y) { // to simplify the loop below,
// otherwise adjust the x significand upwards
// __mul_64x64_to_128MACH (sig_n_prime, sig_x, bid_mult_factor[exp_x - exp_y]); // @AD: Note: The __mul_64x64_to_128MACH macro is the same as __mul_64x64_to_128
{
final long __CY = bid_mult_factor[exp_x - exp_y];
sig_n_prime_w1 = Mul64Impl.unsignedMultiplyHigh(sig_x, __CY);
sig_n_prime_w0 = sig_x * __CY;
}
// if postitive, return whichever significand is larger (converse if neg.)
if (sig_n_prime_w1 == 0 && (sig_n_prime_w0 == sig_y)) {
return false;
}
return (((/*UnsignedLong.isGreater*/(sig_n_prime_w1 != 0))
|| UnsignedLong.isGreater(sig_n_prime_w0, sig_y)) ^ (x_mask_sign));
}
// adjust the y significand upwards
// __mul_64x64_to_128MACH (sig_n_prime, sig_y, bid_mult_factor[exp_y - exp_x]); // @AD: Note: The __mul_64x64_to_128MACH macro is the same as __mul_64x64_to_128
{
final long __CY = bid_mult_factor[exp_y - exp_x];
sig_n_prime_w1 = Mul64Impl.unsignedMultiplyHigh(sig_y, __CY);
sig_n_prime_w0 = sig_y * __CY;
}
// if positive, return whichever significand is larger
// (converse if negative)
if (sig_n_prime_w1 == 0 && (sig_n_prime_w0 == sig_x)) {
return false;
}
return (((sig_n_prime_w1 == 0)
&& (UnsignedLong.isGreater(sig_x, sig_n_prime_w0))) ^ (x_mask_sign));
}