in java/dfp/src/main/java/com/epam/deltix/dfp/JavaImpl.java [2425:3227]
public static long roundToReciprocal(final long value, final int r, final RoundingMode roundType) {
if (r < 1)
throw new IllegalArgumentException("The r(=" + r + ") argument must be positive.");
if (isNonFinite(value))
return value;
// if (Math.log10(r) > JavaImpl.MAX_EXPONENT) // Never can happens
// return value;
// if (Math.log10(r) < JavaImpl.MIN_EXPONENT)
// return JavaImpl.ZERO;
// final Decimal64Parts parts = tlsDecimal64Parts.get();
// JavaImpl.toParts(value, parts);
long partsCoefficient;
long partsSignMask;
int partsExponent;
{ // Copy-paste the toParts method for speedup
partsSignMask = value & MASK_SIGN;
if (isSpecial(value)) {
// if (isNonFinite(value)) {
// partsExponent = 0;
//
// partsCoefficient = value & 0xFE03_FFFF_FFFF_FFFFL;
// if ((value & 0x0003_FFFF_FFFF_FFFFL) > MAX_COEFFICIENT)
// partsCoefficient = value & ~MASK_COEFFICIENT;
// if (isInfinity(value))
// partsCoefficient = value & MASK_SIGN_INFINITY_NAN; // TODO: Why this was done??
// } else
{
// Check for non-canonical values.
final long coefficient = (value & LARGE_COEFFICIENT_MASK) | LARGE_COEFFICIENT_HIGH_BIT;
partsCoefficient = coefficient > MAX_COEFFICIENT ? 0 : coefficient;
// Extract exponent.
final long tmp = value >> EXPONENT_SHIFT_LARGE;
partsExponent = (int) (tmp & EXPONENT_MASK);
}
} else {
// Extract exponent. Maximum biased value for "small exponent" is 0x2FF(*2=0x5FE), signed: []
// upper 1/4 of the mask range is "special", as checked in the code above
final long tmp = value >> EXPONENT_SHIFT_SMALL;
partsExponent = (int) (tmp & EXPONENT_MASK);
// Extract coefficient.
partsCoefficient = (value & SMALL_COEFFICIENT_MASK);
}
}
if (partsCoefficient == 0)
return Decimal64Utils.ZERO;
int unbiasedExponent = partsExponent - JavaImpl.EXPONENT_BIAS;
if (unbiasedExponent >= 0) // value is already rounded
return value;
// Denormalize partsCoefficient to the maximal value to get the maximal precision after final r division
{
final int dn = numberOfDigits(partsCoefficient);
/*if (dn < POWERS_OF_TEN.length - 1)*/
{
final int expShift = (POWERS_OF_TEN.length - 1) - dn;
partsExponent -= expShift;
unbiasedExponent -= expShift;
partsCoefficient *= POWERS_OF_TEN[expShift];
}
}
//Multiply partsCoefficient with r
long coefficientMulR_w0, coefficientMulR_w21;
{
final long l0 = (LONG_LOW_PART & partsCoefficient) * r;
coefficientMulR_w0 = LONG_LOW_PART & l0;
coefficientMulR_w21 = (partsCoefficient >>> 32) * r + (l0 >>> 32);
}
//final long divFactor;
final int divFactor01, divFactor02, divFactor03; // divFactor = divFactor1 * divFactor2 * divFactor3
final int addExponent;
{
int absPower = -unbiasedExponent;
final int maxPower = Math.min(absPower, Math.min(3 * 9, numberOfDigits(coefficientMulR_w21) + 10 /* low part */));
// divFactor = POWERS_OF_TEN[maxPower];
final int factor1Power = Math.min(maxPower, 9); // Int can hold max 1_000_000_000
divFactor01 = (int) POWERS_OF_TEN[factor1Power];
final int factor2Power = Math.min(maxPower - factor1Power, 9);
divFactor02 = (int) POWERS_OF_TEN[factor2Power];
divFactor03 = (int) POWERS_OF_TEN[maxPower - factor1Power - factor2Power];
addExponent = absPower - maxPower;
}
// Process last digit
switch (roundType) {
case UP:
// partsCoefficient = addExponent == 0 ? ((partsCoefficient + divFactor - 1) / divFactor) * divFactor : divFactor;
if (addExponent != 0) {
{
final long divFactor12 = (long) divFactor01 * divFactor02;
coefficientMulR_w0 = LONG_LOW_PART & divFactor12;
coefficientMulR_w21 = divFactor12 >>> 32;
if (divFactor03 > 1) {
final long lowMul = coefficientMulR_w0 * divFactor03;
coefficientMulR_w0 = lowMul & LONG_LOW_PART;
coefficientMulR_w21 = coefficientMulR_w21 * divFactor03 + (lowMul >>> 32);
}
}
} else { // addExponent != 0
{ // + divFactor - 1
long divFactor_w0, divFactor_w21;
{
final long lowPart = (long) divFactor01 * divFactor02;
divFactor_w0 = lowPart & LONG_LOW_PART;
divFactor_w21 = lowPart >>> 32;
}
if (divFactor03 > 1) {
final long lowMul = divFactor_w0 * divFactor03;
divFactor_w0 = lowMul & LONG_LOW_PART;
divFactor_w21 = divFactor_w21 * divFactor03 + (lowMul >>> 32);
}
{ // divFactor - 1
final long lowPart = divFactor_w0 + 0xFFFFFFFFL;
divFactor_w0 = lowPart & LONG_LOW_PART;
divFactor_w21 = divFactor_w21 + 0xFFFFFFFFFFFFFFFFL + (lowPart >>> 32);
}
{
final long lowPart = coefficientMulR_w0 + divFactor_w0;
coefficientMulR_w0 = lowPart & LONG_LOW_PART;
coefficientMulR_w21 += divFactor_w21 + (lowPart >>> 32);
}
}
{ // / divFactor
{
final long r21 = coefficientMulR_w21 % divFactor01;
coefficientMulR_w21 /= divFactor01;
coefficientMulR_w0 = ((r21 << 32) | coefficientMulR_w0) / divFactor01;
}
if (divFactor02 > 1) {
final long r21 = coefficientMulR_w21 % divFactor02;
coefficientMulR_w21 /= divFactor02;
coefficientMulR_w0 = ((r21 << 32) | coefficientMulR_w0) / divFactor02;
}
if (divFactor03 > 1) {
final long r21 = coefficientMulR_w21 % divFactor03;
coefficientMulR_w21 /= divFactor03;
coefficientMulR_w0 = ((r21 << 32) | coefficientMulR_w0) / divFactor03;
}
}
{ // * divFactor
{
final long lowMul = coefficientMulR_w0 * divFactor01;
coefficientMulR_w0 = lowMul & LONG_LOW_PART;
coefficientMulR_w21 = coefficientMulR_w21 * divFactor01 + (lowMul >>> 32);
}
if (divFactor02 > 1) {
final long lowMul = coefficientMulR_w0 * divFactor02;
coefficientMulR_w0 = lowMul & LONG_LOW_PART;
coefficientMulR_w21 = coefficientMulR_w21 * divFactor02 + (lowMul >>> 32);
}
if (divFactor03 > 1) {
final long lowMul = coefficientMulR_w0 * divFactor03;
coefficientMulR_w0 = lowMul & LONG_LOW_PART;
coefficientMulR_w21 = coefficientMulR_w21 * divFactor03 + (lowMul >>> 32);
}
}
}
// partsCoefficient = addExponent == 0 ? ((partsCoefficient + divFactor - 1) / divFactor) * divFactor : divFactor;
break;
case DOWN:
// partsCoefficient = addExponent == 0 ? (partsCoefficient / divFactor) * divFactor : 0;
if (addExponent != 0) {
{
coefficientMulR_w0 = 0;
coefficientMulR_w21 = 0;
}
} else { // addExponent != 0
{ // / divFactor
{
final long r21 = coefficientMulR_w21 % divFactor01;
coefficientMulR_w21 /= divFactor01;
coefficientMulR_w0 = ((r21 << 32) | coefficientMulR_w0) / divFactor01;
}
if (divFactor02 > 1) {
final long r21 = coefficientMulR_w21 % divFactor02;
coefficientMulR_w21 /= divFactor02;
coefficientMulR_w0 = ((r21 << 32) | coefficientMulR_w0) / divFactor02;
}
if (divFactor03 > 1) {
final long r21 = coefficientMulR_w21 % divFactor03;
coefficientMulR_w21 /= divFactor03;
coefficientMulR_w0 = ((r21 << 32) | coefficientMulR_w0) / divFactor03;
}
}
{ // * divFactor
{
final long lowMul = coefficientMulR_w0 * divFactor01;
coefficientMulR_w0 = lowMul & LONG_LOW_PART;
coefficientMulR_w21 = coefficientMulR_w21 * divFactor01 + (lowMul >>> 32);
}
if (divFactor02 > 1) {
final long lowMul = coefficientMulR_w0 * divFactor02;
coefficientMulR_w0 = lowMul & LONG_LOW_PART;
coefficientMulR_w21 = coefficientMulR_w21 * divFactor02 + (lowMul >>> 32);
}
if (divFactor03 > 1) {
final long lowMul = coefficientMulR_w0 * divFactor03;
coefficientMulR_w0 = lowMul & LONG_LOW_PART;
coefficientMulR_w21 = coefficientMulR_w21 * divFactor03 + (lowMul >>> 32);
}
}
}
// partsCoefficient = addExponent == 0 ? (partsCoefficient / divFactor) * divFactor : 0;
break;
case CEILING:
if (partsSignMask >= 0/*!parts.isNegative()*/) {
// partsCoefficient = addExponent == 0 ? ((partsCoefficient + divFactor - 1) / divFactor) * divFactor : divFactor;
if (addExponent != 0) {
{
final long divFactor12 = (long) divFactor01 * divFactor02;
coefficientMulR_w0 = LONG_LOW_PART & divFactor12;
coefficientMulR_w21 = divFactor12 >>> 32;
if (divFactor03 > 1) {
final long lowMul = coefficientMulR_w0 * divFactor03;
coefficientMulR_w0 = lowMul & LONG_LOW_PART;
coefficientMulR_w21 = coefficientMulR_w21 * divFactor03 + (lowMul >>> 32);
}
}
} else { // addExponent != 0
{ // + divFactor - 1
long divFactor_w0, divFactor_w21;
{
final long lowPart = (long) divFactor01 * divFactor02;
divFactor_w0 = lowPart & LONG_LOW_PART;
divFactor_w21 = lowPart >>> 32;
}
if (divFactor03 > 1) {
final long lowMul = divFactor_w0 * divFactor03;
divFactor_w0 = lowMul & LONG_LOW_PART;
divFactor_w21 = divFactor_w21 * divFactor03 + (lowMul >>> 32);
}
{ // divFactor - 1
final long lowPart = divFactor_w0 + 0xFFFFFFFFL;
divFactor_w0 = lowPart & LONG_LOW_PART;
divFactor_w21 = divFactor_w21 + 0xFFFFFFFFFFFFFFFFL + (lowPart >>> 32);
}
{
final long lowPart = coefficientMulR_w0 + divFactor_w0;
coefficientMulR_w0 = lowPart & LONG_LOW_PART;
coefficientMulR_w21 += divFactor_w21 + (lowPart >>> 32);
}
}
{ // / divFactor
{
final long r21 = coefficientMulR_w21 % divFactor01;
coefficientMulR_w21 /= divFactor01;
coefficientMulR_w0 = ((r21 << 32) | coefficientMulR_w0) / divFactor01;
}
if (divFactor02 > 1) {
final long r21 = coefficientMulR_w21 % divFactor02;
coefficientMulR_w21 /= divFactor02;
coefficientMulR_w0 = ((r21 << 32) | coefficientMulR_w0) / divFactor02;
}
if (divFactor03 > 1) {
final long r21 = coefficientMulR_w21 % divFactor03;
coefficientMulR_w21 /= divFactor03;
coefficientMulR_w0 = ((r21 << 32) | coefficientMulR_w0) / divFactor03;
}
}
{ // * divFactor
{
final long lowMul = coefficientMulR_w0 * divFactor01;
coefficientMulR_w0 = lowMul & LONG_LOW_PART;
coefficientMulR_w21 = coefficientMulR_w21 * divFactor01 + (lowMul >>> 32);
}
if (divFactor02 > 1) {
final long lowMul = coefficientMulR_w0 * divFactor02;
coefficientMulR_w0 = lowMul & LONG_LOW_PART;
coefficientMulR_w21 = coefficientMulR_w21 * divFactor02 + (lowMul >>> 32);
}
if (divFactor03 > 1) {
final long lowMul = coefficientMulR_w0 * divFactor03;
coefficientMulR_w0 = lowMul & LONG_LOW_PART;
coefficientMulR_w21 = coefficientMulR_w21 * divFactor03 + (lowMul >>> 32);
}
}
}
// partsCoefficient = addExponent == 0 ? ((partsCoefficient + divFactor - 1) / divFactor) * divFactor : divFactor;
} else { // partsSignMask >= 0
// partsCoefficient = addExponent == 0 ? (partsCoefficient / divFactor) * divFactor : 0;
if (addExponent != 0) {
{
coefficientMulR_w0 = 0;
coefficientMulR_w21 = 0;
}
} else { // addExponent != 0
{ // / divFactor
{
final long r21 = coefficientMulR_w21 % divFactor01;
coefficientMulR_w21 /= divFactor01;
coefficientMulR_w0 = ((r21 << 32) | coefficientMulR_w0) / divFactor01;
}
if (divFactor02 > 1) {
final long r21 = coefficientMulR_w21 % divFactor02;
coefficientMulR_w21 /= divFactor02;
coefficientMulR_w0 = ((r21 << 32) | coefficientMulR_w0) / divFactor02;
}
if (divFactor03 > 1) {
final long r21 = coefficientMulR_w21 % divFactor03;
coefficientMulR_w21 /= divFactor03;
coefficientMulR_w0 = ((r21 << 32) | coefficientMulR_w0) / divFactor03;
}
}
{ // * divFactor
{
final long lowMul = coefficientMulR_w0 * divFactor01;
coefficientMulR_w0 = lowMul & LONG_LOW_PART;
coefficientMulR_w21 = coefficientMulR_w21 * divFactor01 + (lowMul >>> 32);
}
if (divFactor02 > 1) {
final long lowMul = coefficientMulR_w0 * divFactor02;
coefficientMulR_w0 = lowMul & LONG_LOW_PART;
coefficientMulR_w21 = coefficientMulR_w21 * divFactor02 + (lowMul >>> 32);
}
if (divFactor03 > 1) {
final long lowMul = coefficientMulR_w0 * divFactor03;
coefficientMulR_w0 = lowMul & LONG_LOW_PART;
coefficientMulR_w21 = coefficientMulR_w21 * divFactor03 + (lowMul >>> 32);
}
}
}
// partsCoefficient = addExponent == 0 ? (partsCoefficient / divFactor) * divFactor : 0;
}
break;
case FLOOR:
if (partsSignMask >= 0/*!parts.isNegative()*/) {
// partsCoefficient = addExponent == 0 ? (partsCoefficient / divFactor) * divFactor : 0;
if (addExponent != 0) {
{
coefficientMulR_w0 = 0;
coefficientMulR_w21 = 0;
}
} else { // addExponent != 0
{ // / divFactor
{
final long r21 = coefficientMulR_w21 % divFactor01;
coefficientMulR_w21 /= divFactor01;
coefficientMulR_w0 = ((r21 << 32) | coefficientMulR_w0) / divFactor01;
}
if (divFactor02 > 1) {
final long r21 = coefficientMulR_w21 % divFactor02;
coefficientMulR_w21 /= divFactor02;
coefficientMulR_w0 = ((r21 << 32) | coefficientMulR_w0) / divFactor02;
}
if (divFactor03 > 1) {
final long r21 = coefficientMulR_w21 % divFactor03;
coefficientMulR_w21 /= divFactor03;
coefficientMulR_w0 = ((r21 << 32) | coefficientMulR_w0) / divFactor03;
}
}
{ // * divFactor
{
final long lowMul = coefficientMulR_w0 * divFactor01;
coefficientMulR_w0 = lowMul & LONG_LOW_PART;
coefficientMulR_w21 = coefficientMulR_w21 * divFactor01 + (lowMul >>> 32);
}
if (divFactor02 > 1) {
final long lowMul = coefficientMulR_w0 * divFactor02;
coefficientMulR_w0 = lowMul & LONG_LOW_PART;
coefficientMulR_w21 = coefficientMulR_w21 * divFactor02 + (lowMul >>> 32);
}
if (divFactor03 > 1) {
final long lowMul = coefficientMulR_w0 * divFactor03;
coefficientMulR_w0 = lowMul & LONG_LOW_PART;
coefficientMulR_w21 = coefficientMulR_w21 * divFactor03 + (lowMul >>> 32);
}
}
}
// partsCoefficient = addExponent == 0 ? (partsCoefficient / divFactor) * divFactor : 0;
} else { // partsSignMask >= 0
// partsCoefficient = addExponent == 0 ? ((partsCoefficient + divFactor - 1) / divFactor) * divFactor : divFactor;
if (addExponent != 0) {
{
final long divFactor12 = (long) divFactor01 * divFactor02;
coefficientMulR_w0 = LONG_LOW_PART & divFactor12;
coefficientMulR_w21 = divFactor12 >>> 32;
if (divFactor03 > 1) {
final long lowMul = coefficientMulR_w0 * divFactor03;
coefficientMulR_w0 = lowMul & LONG_LOW_PART;
coefficientMulR_w21 = coefficientMulR_w21 * divFactor03 + (lowMul >>> 32);
}
}
} else { // addExponent != 0
{ // + divFactor - 1
long divFactor_w0, divFactor_w21;
{
final long lowPart = (long) divFactor01 * divFactor02;
divFactor_w0 = lowPart & LONG_LOW_PART;
divFactor_w21 = lowPart >>> 32;
}
if (divFactor03 > 1) {
final long lowMul = divFactor_w0 * divFactor03;
divFactor_w0 = lowMul & LONG_LOW_PART;
divFactor_w21 = divFactor_w21 * divFactor03 + (lowMul >>> 32);
}
{ // divFactor - 1
final long lowPart = divFactor_w0 + 0xFFFFFFFFL;
divFactor_w0 = lowPart & LONG_LOW_PART;
divFactor_w21 = divFactor_w21 + 0xFFFFFFFFFFFFFFFFL + (lowPart >>> 32);
}
{
final long lowPart = coefficientMulR_w0 + divFactor_w0;
coefficientMulR_w0 = lowPart & LONG_LOW_PART;
coefficientMulR_w21 += divFactor_w21 + (lowPart >>> 32);
}
}
{ // / divFactor
{
final long r21 = coefficientMulR_w21 % divFactor01;
coefficientMulR_w21 /= divFactor01;
coefficientMulR_w0 = ((r21 << 32) | coefficientMulR_w0) / divFactor01;
}
if (divFactor02 > 1) {
final long r21 = coefficientMulR_w21 % divFactor02;
coefficientMulR_w21 /= divFactor02;
coefficientMulR_w0 = ((r21 << 32) | coefficientMulR_w0) / divFactor02;
}
if (divFactor03 > 1) {
final long r21 = coefficientMulR_w21 % divFactor03;
coefficientMulR_w21 /= divFactor03;
coefficientMulR_w0 = ((r21 << 32) | coefficientMulR_w0) / divFactor03;
}
}
{ // * divFactor
{
final long lowMul = coefficientMulR_w0 * divFactor01;
coefficientMulR_w0 = lowMul & LONG_LOW_PART;
coefficientMulR_w21 = coefficientMulR_w21 * divFactor01 + (lowMul >>> 32);
}
if (divFactor02 > 1) {
final long lowMul = coefficientMulR_w0 * divFactor02;
coefficientMulR_w0 = lowMul & LONG_LOW_PART;
coefficientMulR_w21 = coefficientMulR_w21 * divFactor02 + (lowMul >>> 32);
}
if (divFactor03 > 1) {
final long lowMul = coefficientMulR_w0 * divFactor03;
coefficientMulR_w0 = lowMul & LONG_LOW_PART;
coefficientMulR_w21 = coefficientMulR_w21 * divFactor03 + (lowMul >>> 32);
}
}
}
// partsCoefficient = addExponent == 0 ? ((partsCoefficient + divFactor - 1) / divFactor) * divFactor : divFactor;
}
break;
case HALF_UP:
// partsCoefficient = addExponent == 0 ? ((partsCoefficient + divFactor / 2) / divFactor) * divFactor : 0;
if (addExponent != 0) {
{
coefficientMulR_w0 = 0;
coefficientMulR_w21 = 0;
}
} else { // addExponent != 0
{ // + divFactor / 2
long divFactor_w0, divFactor_w21;
{
final long lowPart = (long) divFactor01 * divFactor02;
divFactor_w0 = lowPart & LONG_LOW_PART;
divFactor_w21 = lowPart >>> 32;
}
if (divFactor03 > 1) {
final long lowMul = divFactor_w0 * divFactor03;
divFactor_w0 = lowMul & LONG_LOW_PART;
divFactor_w21 = divFactor_w21 * divFactor03 + (lowMul >>> 32);
}
{ // divFactor / 2
divFactor_w0 = ((divFactor_w21 & 1) << 31) | (divFactor_w0 >>> 1);
divFactor_w21 = divFactor_w21 >>> 1;
}
{
final long lowPart = coefficientMulR_w0 + divFactor_w0;
coefficientMulR_w0 = lowPart & LONG_LOW_PART;
coefficientMulR_w21 += divFactor_w21 + (lowPart >>> 32);
}
}
{ // / divFactor
{
final long r21 = coefficientMulR_w21 % divFactor01;
coefficientMulR_w21 /= divFactor01;
coefficientMulR_w0 = ((r21 << 32) | coefficientMulR_w0) / divFactor01;
}
if (divFactor02 > 1) {
final long r21 = coefficientMulR_w21 % divFactor02;
coefficientMulR_w21 /= divFactor02;
coefficientMulR_w0 = ((r21 << 32) | coefficientMulR_w0) / divFactor02;
}
if (divFactor03 > 1) {
final long r21 = coefficientMulR_w21 % divFactor03;
coefficientMulR_w21 /= divFactor03;
coefficientMulR_w0 = ((r21 << 32) | coefficientMulR_w0) / divFactor03;
}
}
{ // * divFactor
{
final long lowMul = coefficientMulR_w0 * divFactor01;
coefficientMulR_w0 = lowMul & LONG_LOW_PART;
coefficientMulR_w21 = coefficientMulR_w21 * divFactor01 + (lowMul >>> 32);
}
if (divFactor02 > 1) {
final long lowMul = coefficientMulR_w0 * divFactor02;
coefficientMulR_w0 = lowMul & LONG_LOW_PART;
coefficientMulR_w21 = coefficientMulR_w21 * divFactor02 + (lowMul >>> 32);
}
if (divFactor03 > 1) {
final long lowMul = coefficientMulR_w0 * divFactor03;
coefficientMulR_w0 = lowMul & LONG_LOW_PART;
coefficientMulR_w21 = coefficientMulR_w21 * divFactor03 + (lowMul >>> 32);
}
}
}
// partsCoefficient = addExponent == 0 ? ((partsCoefficient + divFactor / 2) / divFactor) * divFactor : 0;
break;
case HALF_DOWN:
// partsCoefficient = addExponent == 0 ? ((partsCoefficient + divFactor / 2 - 1) / divFactor) * divFactor : 0;
if (addExponent != 0) {
{
coefficientMulR_w0 = 0;
coefficientMulR_w21 = 0;
}
} else { // addExponent != 0
{ // + divFactor / 2
long divFactor_w0, divFactor_w21;
{
final long lowPart = (long) divFactor01 * divFactor02;
divFactor_w0 = lowPart & LONG_LOW_PART;
divFactor_w21 = lowPart >>> 32;
}
if (divFactor03 > 1) {
final long lowMul = divFactor_w0 * divFactor03;
divFactor_w0 = lowMul & LONG_LOW_PART;
divFactor_w21 = divFactor_w21 * divFactor03 + (lowMul >>> 32);
}
{ // divFactor / 2
divFactor_w0 = ((divFactor_w21 & 1) << 31) | (divFactor_w0 >>> 1);
divFactor_w21 = divFactor_w21 >>> 1;
}
{ // divFactor - 1
final long lowPart = divFactor_w0 + 0xFFFFFFFFL;
divFactor_w0 = lowPart & LONG_LOW_PART;
divFactor_w21 = divFactor_w21 + 0xFFFFFFFFFFFFFFFFL + (lowPart >>> 32);
}
{
final long lowPart = coefficientMulR_w0 + divFactor_w0;
coefficientMulR_w0 = lowPart & LONG_LOW_PART;
coefficientMulR_w21 += divFactor_w21 + (lowPart >>> 32);
}
}
{ // / divFactor
{
final long r21 = coefficientMulR_w21 % divFactor01;
coefficientMulR_w21 /= divFactor01;
coefficientMulR_w0 = ((r21 << 32) | coefficientMulR_w0) / divFactor01;
}
if (divFactor02 > 1) {
final long r21 = coefficientMulR_w21 % divFactor02;
coefficientMulR_w21 /= divFactor02;
coefficientMulR_w0 = ((r21 << 32) | coefficientMulR_w0) / divFactor02;
}
if (divFactor03 > 1) {
final long r21 = coefficientMulR_w21 % divFactor03;
coefficientMulR_w21 /= divFactor03;
coefficientMulR_w0 = ((r21 << 32) | coefficientMulR_w0) / divFactor03;
}
}
{ // * divFactor
{
final long lowMul = coefficientMulR_w0 * divFactor01;
coefficientMulR_w0 = lowMul & LONG_LOW_PART;
coefficientMulR_w21 = coefficientMulR_w21 * divFactor01 + (lowMul >>> 32);
}
if (divFactor02 > 1) {
final long lowMul = coefficientMulR_w0 * divFactor02;
coefficientMulR_w0 = lowMul & LONG_LOW_PART;
coefficientMulR_w21 = coefficientMulR_w21 * divFactor02 + (lowMul >>> 32);
}
if (divFactor03 > 1) {
final long lowMul = coefficientMulR_w0 * divFactor03;
coefficientMulR_w0 = lowMul & LONG_LOW_PART;
coefficientMulR_w21 = coefficientMulR_w21 * divFactor03 + (lowMul >>> 32);
}
}
}
// partsCoefficient = addExponent == 0 ? ((partsCoefficient + divFactor / 2 - 1) / divFactor) * divFactor : 0;
break;
case HALF_EVEN:
// partsCoefficient = addExponent == 0 ? ((partsCoefficient + divFactor / 2 - 1 + ((partsCoefficient / divFactor) & 1L)) / divFactor) * divFactor : 0;
if (addExponent != 0) {
{
coefficientMulR_w0 = 0;
coefficientMulR_w21 = 0;
}
} else { // addExponent != 0
{ // + divFactor / 2
long divFactor_w0, divFactor_w21;
{
final long lowPart = (long) divFactor01 * divFactor02;
divFactor_w0 = lowPart & LONG_LOW_PART;
divFactor_w21 = lowPart >>> 32;
}
if (divFactor03 > 1) {
final long lowMul = divFactor_w0 * divFactor03;
divFactor_w0 = lowMul & LONG_LOW_PART;
divFactor_w21 = divFactor_w21 * divFactor03 + (lowMul >>> 32);
}
{ // divFactor / 2
divFactor_w0 = ((divFactor_w21 & 1) << 31) | (divFactor_w0 >>> 1);
divFactor_w21 = divFactor_w21 >>> 1;
}
final boolean divisionLatestBit;
{ // ((partsCoefficient / divFactor) & 1L)
long tmpCoefficientMulR_w0 = coefficientMulR_w0;
long tmpCoefficientMulR_w21 = coefficientMulR_w21;
{ // / divFactor
{
final long r21 = tmpCoefficientMulR_w21 % divFactor01;
tmpCoefficientMulR_w21 /= divFactor01;
tmpCoefficientMulR_w0 = ((r21 << 32) | tmpCoefficientMulR_w0) / divFactor01;
}
if (divFactor02 > 1) {
final long r21 = tmpCoefficientMulR_w21 % divFactor02;
tmpCoefficientMulR_w21 /= divFactor02;
tmpCoefficientMulR_w0 = ((r21 << 32) | tmpCoefficientMulR_w0) / divFactor02;
}
if (divFactor03 > 1) {
final long r21 = tmpCoefficientMulR_w21 % divFactor03;
// tmpCoefficientMulR_w21 /= divFactor03; // No need high words
tmpCoefficientMulR_w0 = ((r21 << 32) | tmpCoefficientMulR_w0) / divFactor03;
}
}
divisionLatestBit = (tmpCoefficientMulR_w0 & 1) != 0;
}
if (!divisionLatestBit) { // divFactor - 1
final long lowPart = divFactor_w0 + 0xFFFFFFFFL;
divFactor_w0 = lowPart & LONG_LOW_PART;
divFactor_w21 = divFactor_w21 + 0xFFFFFFFFFFFFFFFFL + (lowPart >>> 32);
}
{
final long lowPart = coefficientMulR_w0 + divFactor_w0;
coefficientMulR_w0 = lowPart & LONG_LOW_PART;
coefficientMulR_w21 += divFactor_w21 + (lowPart >>> 32);
}
}
{ // / divFactor
{
final long r21 = coefficientMulR_w21 % divFactor01;
coefficientMulR_w21 /= divFactor01;
coefficientMulR_w0 = ((r21 << 32) | coefficientMulR_w0) / divFactor01;
}
if (divFactor02 > 1) {
final long r21 = coefficientMulR_w21 % divFactor02;
coefficientMulR_w21 /= divFactor02;
coefficientMulR_w0 = ((r21 << 32) | coefficientMulR_w0) / divFactor02;
}
if (divFactor03 > 1) {
final long r21 = coefficientMulR_w21 % divFactor03;
coefficientMulR_w21 /= divFactor03;
coefficientMulR_w0 = ((r21 << 32) | coefficientMulR_w0) / divFactor03;
}
}
{ // * divFactor
{
final long lowMul = coefficientMulR_w0 * divFactor01;
coefficientMulR_w0 = lowMul & LONG_LOW_PART;
coefficientMulR_w21 = coefficientMulR_w21 * divFactor01 + (lowMul >>> 32);
}
if (divFactor02 > 1) {
final long lowMul = coefficientMulR_w0 * divFactor02;
coefficientMulR_w0 = lowMul & LONG_LOW_PART;
coefficientMulR_w21 = coefficientMulR_w21 * divFactor02 + (lowMul >>> 32);
}
if (divFactor03 > 1) {
final long lowMul = coefficientMulR_w0 * divFactor03;
coefficientMulR_w0 = lowMul & LONG_LOW_PART;
coefficientMulR_w21 = coefficientMulR_w21 * divFactor03 + (lowMul >>> 32);
}
}
}
// partsCoefficient = addExponent == 0 ? ((partsCoefficient + divFactor / 2 - 1 + ((partsCoefficient / divFactor) & 1L)) / divFactor) * divFactor : 0;
break;
case UNNECESSARY:
if (!isRoundedToReciprocalImpl(
addExponent, coefficientMulR_w21, coefficientMulR_w0,
divFactor01, divFactor02, divFactor03))
throw new ArithmeticException("Rounding necessary");
return value;
default:
throw new IllegalArgumentException("Unsupported roundType(=" + roundType + ") value.");
}
{ // / r
final long r21 = coefficientMulR_w21 % r;
coefficientMulR_w21 /= r;
coefficientMulR_w0 = ((r21 << 32) | coefficientMulR_w0) / r;
if (coefficientMulR_w21 > Integer.MAX_VALUE) {
final int dn = numberOfDigits(coefficientMulR_w21 / Integer.MAX_VALUE);
final int f = (int) POWERS_OF_TEN[dn];
partsExponent += dn;
{
final long f21 = coefficientMulR_w21 % f;
coefficientMulR_w21 /= f;
coefficientMulR_w0 = ((f21 << 32) | coefficientMulR_w0) / f;
}
}
partsCoefficient = ((LONG_LOW_PART & coefficientMulR_w21) << 32) + coefficientMulR_w0;
}
partsExponent += addExponent;
if (partsCoefficient == 0)
return JavaImpl.ZERO;
return pack(partsSignMask, partsExponent, partsCoefficient, BID_ROUNDING_TO_NEAREST); // JavaImpl.fromParts(parts)
}