in commons-math-legacy-core/src/main/java/org/apache/commons/math4/legacy/core/dfp/Dfp.java [1042:1126]
protected Dfp trunc(final DfpField.RoundingMode rmode) {
boolean changed = false;
if (isNaN()) {
return newInstance(this);
}
if (nans == INFINITE) {
return newInstance(this);
}
if (mant[mant.length - 1] == 0) {
// a is zero
return newInstance(this);
}
/* If the exponent is less than zero then we can certainly
* return zero */
if (exp < 0) {
field.setIEEEFlagsBits(DfpField.FLAG_INEXACT);
Dfp result = newInstance(getZero());
result = dotrap(DfpField.FLAG_INEXACT, TRUNC_TRAP, this, result);
return result;
}
/* If the exponent is greater than or equal to digits, then it
* must already be an integer since there is no precision left
* for any fractional part */
if (exp >= mant.length) {
return newInstance(this);
}
/* General case: create another dfp, result, that contains the
* a with the fractional part lopped off. */
Dfp result = newInstance(this);
for (int i = 0; i < mant.length - result.exp; i++) {
changed |= result.mant[i] != 0;
result.mant[i] = 0;
}
if (changed) {
switch (rmode) {
case ROUND_FLOOR:
if (result.sign == -1) {
// then we must increment the mantissa by one
result = result.add(newInstance(-1));
}
break;
case ROUND_CEIL:
if (result.sign == 1) {
// then we must increment the mantissa by one
result = result.add(getOne());
}
break;
case ROUND_HALF_EVEN:
default:
final Dfp half = newInstance("0.5");
Dfp a = subtract(result); // difference between this and result
a.sign = 1; // force positive (take abs)
if (a.greaterThan(half)) {
a = newInstance(getOne());
a.sign = sign;
result = result.add(a);
}
/* If exactly equal to 1/2 and odd then increment */
if (a.equals(half) && result.exp > 0 && (result.mant[mant.length - result.exp] & 1) != 0) {
a = newInstance(getOne());
a.sign = sign;
result = result.add(a);
}
break;
}
field.setIEEEFlagsBits(DfpField.FLAG_INEXACT); // signal inexact
result = dotrap(DfpField.FLAG_INEXACT, TRUNC_TRAP, this, result);
return result;
}
return result;
}