/** * Finds the Decimal KeyRange that will produce the given result when fed into this * rounding expression. For example, a ROUND expression with scale 2 will produce the * result "2.05" with any decimal in the range [2.045, 2.0545). * The result must be pre-rounded to within this rounding expression's scale. * @param result the result to find an input range for. Must be producable. * @return a KeyRange of DECIMAL keys that can be rounded by this expression to produce result * @throws IllegalArgumentException if the result has more scale than this expression can produce */ protected KeyRange getInputRangeProducing(BigDecimal result) { if(!hasEnoughPrecisionToProduce(result)) { throw new IllegalArgumentException("Cannot produce input range for decimal " + result + ", not enough precision with scale " + getRoundingScale()); } byte[] lowerRange = PDecimal.INSTANCE.toBytes(halfStepPrevInScale(result)); byte[] upperRange = PDecimal.INSTANCE.toBytes(halfStepNextInScale(result)); // inclusiveness changes depending on sign // e.g. -0.5 rounds "up" to -1 even though it is the lower boundary boolean lowerInclusive = result.signum() > 0; boolean upperInclusive = result.signum() < 0; return KeyRange.getKeyRange(lowerRange, lowerInclusive, upperRange, upperInclusive); }
/** * Finds the Decimal KeyRange that will produce the given result when fed into this * rounding expression. For example, a ROUND expression with scale 2 will produce the * result "2.05" with any decimal in the range [2.045, 2.0545). * The result must be pre-rounded to within this rounding expression's scale. * @param result the result to find an input range for. Must be producable. * @return a KeyRange of DECIMAL keys that can be rounded by this expression to produce result * @throws IllegalArgumentException if the result has more scale than this expression can produce */ protected KeyRange getInputRangeProducing(BigDecimal result) { if(!hasEnoughPrecisionToProduce(result)) { throw new IllegalArgumentException("Cannot produce input range for decimal " + result + ", not enough precision with scale " + getRoundingScale()); } byte[] lowerRange = PDecimal.INSTANCE.toBytes(halfStepPrevInScale(result)); byte[] upperRange = PDecimal.INSTANCE.toBytes(halfStepNextInScale(result)); // inclusiveness changes depending on sign // e.g. -0.5 rounds "up" to -1 even though it is the lower boundary boolean lowerInclusive = result.signum() > 0; boolean upperInclusive = result.signum() < 0; return KeyRange.getKeyRange(lowerRange, lowerInclusive, upperRange, upperInclusive); }
/** * Finds the Decimal KeyRange that will produce the given result when fed into this * rounding expression. For example, a ROUND expression with scale 2 will produce the * result "2.05" with any decimal in the range [2.045, 2.0545). * The result must be pre-rounded to within this rounding expression's scale. * @param result the result to find an input range for. Must be producable. * @return a KeyRange of DECIMAL keys that can be rounded by this expression to produce result * @throws IllegalArgumentException if the result has more scale than this expression can produce */ protected KeyRange getInputRangeProducing(BigDecimal result) { if(!hasEnoughPrecisionToProduce(result)) { throw new IllegalArgumentException("Cannot produce input range for decimal " + result + ", not enough precision with scale " + getRoundingScale()); } byte[] lowerRange = PDecimal.INSTANCE.toBytes(halfStepPrevInScale(result)); byte[] upperRange = PDecimal.INSTANCE.toBytes(halfStepNextInScale(result)); // inclusiveness changes depending on sign // e.g. -0.5 rounds "up" to -1 even though it is the lower boundary boolean lowerInclusive = result.signum() > 0; boolean upperInclusive = result.signum() < 0; return KeyRange.getKeyRange(lowerRange, lowerInclusive, upperRange, upperInclusive); }