public override ValueEval Evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) { double dn; try { ValueEval ve1 = OperandResolver.GetSingleValue(arg1, srcRowIndex, srcColumnIndex); dn = OperandResolver.CoerceValueToDouble(ve1); } catch (EvaluationException) { // all errors in the second arg translate to #VALUE! return(ErrorEval.VALUE_INVALID); } if (dn < 0 || dn > 1) { // has to be percentage return(ErrorEval.NUM_ERROR); } double result; try { double[] ds = Npoi.Core.SS.Formula.Functions.AggregateFunction.ValueCollector.CollectValues(arg0); int N = ds.Length; if (N == 0 || N > 8191) { return(ErrorEval.NUM_ERROR); } double n = (N - 1) * dn + 1; if (n == 1d) { result = StatsLib.kthSmallest(ds, 1); } else if (n == N) { result = StatsLib.kthLargest(ds, 1); } else { int k = (int)n; double d = n - k; result = StatsLib.kthSmallest(ds, k) + d * (StatsLib.kthSmallest(ds, k + 1) - StatsLib.kthSmallest(ds, k)); } NumericFunction.CheckValue(result); } catch (EvaluationException e) { return(e.GetErrorEval()); } return(new NumberEval(result)); }
protected internal override double Evaluate(double[] ops) { if (ops.Length < 2) { throw new EvaluationException(ErrorEval.NUM_ERROR); } double[] values = new double[ops.Length - 1]; int k = (int)ops[ops.Length - 1]; System.Array.Copy(ops, 0, values, 0, values.Length); return(StatsLib.kthSmallest(values, k)); }
public override ValueEval Evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) { double dn; try { ValueEval ve1 = OperandResolver.GetSingleValue(arg1, srcRowIndex, srcColumnIndex); dn = OperandResolver.CoerceValueToDouble(ve1); } catch (EvaluationException) { // all errors in the second arg translate to #VALUE! return(ErrorEval.VALUE_INVALID); } // weird Excel behaviour on second arg if (dn < 1.0) { // values between 0.0 and 1.0 result in #NUM! return(ErrorEval.NUM_ERROR); } // all other values are rounded up to the next integer int k = (int)Math.Ceiling(dn); double result; try { double[] ds = Npoi.Core.SS.Formula.Functions.AggregateFunction.ValueCollector.CollectValues(arg0); if (k > ds.Length) { return(ErrorEval.NUM_ERROR); } result = _isLarge ? StatsLib.kthLargest(ds, k) : StatsLib.kthSmallest(ds, k); NumericFunction.CheckValue(result); } catch (EvaluationException e) { return(e.GetErrorEval()); } return(new NumberEval(result)); }