From: PJ Fanning Date: Thu, 31 Mar 2022 20:13:49 +0000 (+0000) Subject: reformat file X-Git-Tag: REL_5_2_3~384 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=9d89bc160408c0f44bba421f9ee196a21c0c9095;p=poi.git reformat file git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1899455 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/poi/src/main/java/org/apache/poi/ss/formula/functions/Rate.java b/poi/src/main/java/org/apache/poi/ss/formula/functions/Rate.java index 484be43a96..4ecd4c794e 100644 --- a/poi/src/main/java/org/apache/poi/ss/formula/functions/Rate.java +++ b/poi/src/main/java/org/apache/poi/ss/formula/functions/Rate.java @@ -31,94 +31,94 @@ import org.apache.poi.ss.formula.eval.ValueEval; public class Rate implements Function { private static final Logger LOG = LogManager.getLogger(Rate.class); - @Override - public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) { - if (args.length < 3) { //First 3 parameters are mandatory - return ErrorEval.VALUE_INVALID; - } - - double periods, payment, present_val, future_val = 0, type = 0, estimate = 0.1, rate; - - try { - ValueEval v1 = OperandResolver.getSingleValue(args[0], srcRowIndex, srcColumnIndex); - ValueEval v2 = OperandResolver.getSingleValue(args[1], srcRowIndex, srcColumnIndex); - ValueEval v3 = OperandResolver.getSingleValue(args[2], srcRowIndex, srcColumnIndex); - ValueEval v4 = null; - if (args.length >= 4) - v4 = OperandResolver.getSingleValue(args[3], srcRowIndex, srcColumnIndex); - ValueEval v5 = null; - if (args.length >= 5) - v5 = OperandResolver.getSingleValue(args[4], srcRowIndex, srcColumnIndex); - ValueEval v6 = null; - if (args.length >= 6) - v6 = OperandResolver.getSingleValue(args[5], srcRowIndex, srcColumnIndex); - - periods = OperandResolver.coerceValueToDouble(v1); - payment = OperandResolver.coerceValueToDouble(v2); - present_val = OperandResolver.coerceValueToDouble(v3); - if (args.length >= 4) - future_val = OperandResolver.coerceValueToDouble(v4); - if (args.length >= 5) - type = OperandResolver.coerceValueToDouble(v5); - if (args.length >= 6) - estimate = OperandResolver.coerceValueToDouble(v6); - rate = calculateRate(periods, payment, present_val, future_val, type, estimate) ; - - checkValue(rate); - } catch (EvaluationException e) { - LOG.atError().withThrowable(e).log("Can't evaluate rate function"); - return e.getErrorEval(); - } - - return new NumberEval( rate ) ; - } - - private double calculateRate(double nper, double pmt, double pv, double fv, double type, double guess) { - //FROM MS http://office.microsoft.com/en-us/excel-help/rate-HP005209232.aspx - int FINANCIAL_MAX_ITERATIONS = 20;//Bet accuracy with 128 - double FINANCIAL_PRECISION = 0.0000001;//1.0e-8 - - double y, y0, y1, x0, x1, f = 0, i; - double rate = guess; - if (Math.abs(rate) < FINANCIAL_PRECISION) { - y = pv * (1 + nper * rate) + pmt * (1 + rate * type) * nper + fv; - } else { - f = Math.exp(nper * Math.log(1 + rate)); - y = pv * f + pmt * (1 / rate + type) * (f - 1) + fv; - } - y0 = pv + pmt * nper + fv; - y1 = pv * f + pmt * (1 / rate + type) * (f - 1) + fv; - - // find root by Newton secant method - i = x0 = 0.0; - x1 = rate; - while ((Math.abs(y0 - y1) > FINANCIAL_PRECISION) && (i < FINANCIAL_MAX_ITERATIONS)) { - rate = (y1 * x0 - y0 * x1) / (y1 - y0); - x0 = x1; - x1 = rate; - - if (Math.abs(rate) < FINANCIAL_PRECISION) { + @Override + public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) { + if (args.length < 3) { //First 3 parameters are mandatory + return ErrorEval.VALUE_INVALID; + } + + double periods, payment, present_val, future_val = 0, type = 0, estimate = 0.1, rate; + + try { + ValueEval v1 = OperandResolver.getSingleValue(args[0], srcRowIndex, srcColumnIndex); + ValueEval v2 = OperandResolver.getSingleValue(args[1], srcRowIndex, srcColumnIndex); + ValueEval v3 = OperandResolver.getSingleValue(args[2], srcRowIndex, srcColumnIndex); + ValueEval v4 = null; + if (args.length >= 4) + v4 = OperandResolver.getSingleValue(args[3], srcRowIndex, srcColumnIndex); + ValueEval v5 = null; + if (args.length >= 5) + v5 = OperandResolver.getSingleValue(args[4], srcRowIndex, srcColumnIndex); + ValueEval v6 = null; + if (args.length >= 6) + v6 = OperandResolver.getSingleValue(args[5], srcRowIndex, srcColumnIndex); + + periods = OperandResolver.coerceValueToDouble(v1); + payment = OperandResolver.coerceValueToDouble(v2); + present_val = OperandResolver.coerceValueToDouble(v3); + if (args.length >= 4) + future_val = OperandResolver.coerceValueToDouble(v4); + if (args.length >= 5) + type = OperandResolver.coerceValueToDouble(v5); + if (args.length >= 6) + estimate = OperandResolver.coerceValueToDouble(v6); + rate = calculateRate(periods, payment, present_val, future_val, type, estimate); + + checkValue(rate); + } catch (EvaluationException e) { + LOG.atError().withThrowable(e).log("Can't evaluate rate function") + return e.getErrorEval(); + } + + return new NumberEval(rate); + } + + private double calculateRate(double nper, double pmt, double pv, double fv, double type, double guess) { + //FROM MS http://office.microsoft.com/en-us/excel-help/rate-HP005209232.aspx + int FINANCIAL_MAX_ITERATIONS = 20;//Bet accuracy with 128 + double FINANCIAL_PRECISION = 0.0000001;//1.0e-8 + + double y, y0, y1, x0, x1, f = 0, i; + double rate = guess; + if (Math.abs(rate) < FINANCIAL_PRECISION) { y = pv * (1 + nper * rate) + pmt * (1 + rate * type) * nper + fv; - } else { + } else { f = Math.exp(nper * Math.log(1 + rate)); y = pv * f + pmt * (1 / rate + type) * (f - 1) + fv; - } - - y0 = y1; - y1 = y; - ++i; - } - return rate; - } - - /** - * Excel does not support infinities and NaNs, rather, it gives a #NUM! error in these cases - * - * @throws EvaluationException (#NUM!) if {@code result} is {@code NaN} or {@code Infinity} - */ - static void checkValue(double result) throws EvaluationException { - if (Double.isNaN(result) || Double.isInfinite(result)) { - throw new EvaluationException(ErrorEval.NUM_ERROR); - } - } + } + y0 = pv + pmt * nper + fv; + y1 = pv * f + pmt * (1 / rate + type) * (f - 1) + fv; + + // find root by Newton secant method + i = x0 = 0.0; + x1 = rate; + while ((Math.abs(y0 - y1) > FINANCIAL_PRECISION) && (i < FINANCIAL_MAX_ITERATIONS)) { + rate = (y1 * x0 - y0 * x1) / (y1 - y0); + x0 = x1; + x1 = rate; + + if (Math.abs(rate) < FINANCIAL_PRECISION) { + y = pv * (1 + nper * rate) + pmt * (1 + rate * type) * nper + fv; + } else { + f = Math.exp(nper * Math.log(1 + rate)); + y = pv * f + pmt * (1 / rate + type) * (f - 1) + fv; + } + + y0 = y1; + y1 = y; + ++i; + } + return rate; + } + + /** + * Excel does not support infinities and NaNs, rather, it gives a #NUM! error in these cases + * + * @throws EvaluationException (#NUM!) if {@code result} is {@code NaN} or {@code Infinity} + */ + static void checkValue(double result) throws EvaluationException { + if (Double.isNaN(result) || Double.isInfinite(result)) { + throw new EvaluationException(ErrorEval.NUM_ERROR); + } + } }