protected Dfp trunc()

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;
    }