/** * Return the SQL scale of this value, number of digits after the decimal point, or zero for a * whole number. This does not match the return from BigDecimal.scale() since in J2SE 5.0 onwards * that can return negative scales. */ public int getDecimalValuePrecision() { if (isNull()) return 0; BigDecimal localValue = getBigDecimal(); return SQLDecimal.getWholeDigits(localValue) + getDecimalValueScale(); }
/** * Set the precision/scale of the to the desired values. Used when CASTing. Ideally we'd recycle * normalize(), but the use is different. * * @param desiredPrecision the desired precision -- IGNORE_PREICISION if it is to be ignored. * @param desiredScale the desired scale * @param errorOnTrunc throw error on truncation (ignored -- always thrown if we truncate the * non-decimal part of the value) * @exception StandardException Thrown on non-zero truncation if errorOnTrunc is true */ public void setWidth(int desiredPrecision, int desiredScale, boolean errorOnTrunc) throws StandardException { if (isNull()) return; if (desiredPrecision != IGNORE_PRECISION && ((desiredPrecision - desiredScale) < SQLDecimal.getWholeDigits(getBigDecimal()))) { throw StandardException.newException( SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE, ("DECIMAL/NUMERIC(" + desiredPrecision + "," + desiredScale + ")")); } value = value.setScale(desiredScale, BigDecimal.ROUND_DOWN); rawData = null; }
/** * This method implements the / operator for BigDecimal/BigDecimal * * @param dividend The numerator * @param divisor The denominator * @param result The result of a previous call to this method, null if not called yet * @param scale The result scale, if < 0, calculate the scale according to the actual values' * sizes * @return A SQLDecimal containing the result of the division * @exception StandardException Thrown on error */ public NumberDataValue divide( NumberDataValue dividend, NumberDataValue divisor, NumberDataValue result, int scale) throws StandardException { if (result == null) { result = new SQLDecimal(); } if (dividend.isNull() || divisor.isNull()) { result.setToNull(); return result; } BigDecimal divisorBigDecimal = SQLDecimal.getBigDecimal(divisor); if (divisorBigDecimal.compareTo(ZERO) == 0) { throw StandardException.newException(SQLState.LANG_DIVIDE_BY_ZERO); } BigDecimal dividendBigDecimal = SQLDecimal.getBigDecimal(dividend); /* ** Set the result scale to be either the passed in scale, whcih was ** calculated at bind time to be max(ls+rp-rs+1, 4), where ls,rp,rs ** are static data types' sizes, which are predictable and stable ** (for the whole result set column, eg.); otherwise dynamically ** calculates the scale according to actual values. Beetle 3901 */ result.setBigDecimal( dividendBigDecimal.divide( divisorBigDecimal, scale > -1 ? scale : Math.max( (dividendBigDecimal.scale() + SQLDecimal.getWholeDigits(divisorBigDecimal) + 1), NumberDataValue.MIN_DECIMAL_DIVIDE_SCALE), BigDecimal.ROUND_DOWN)); return result; }