Add PERCENTILE and QUARTILE function families#1650
Add PERCENTILE and QUARTILE function families#1650marcin-kordas-hoc wants to merge 10 commits intodevelopfrom
Conversation
…C, QUARTILE.EXC functions - New PercentilePlugin with inclusive and exclusive interpolation - Translations for all 17 supported languages (verified via excel-translator.de) - Documentation in built-in-functions.md - CHANGELOG entry Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…lidation - Extract getSortedValues() to eliminate 4x duplicated range-extraction + sort - Remove dead-code guards from percentileInclusive/percentileExclusive helpers - Fix quartile validation: truncate BEFORE range check (Excel truncates 3.9→3) - Remove minValue/maxValue from QUARTILE params — validate post-truncation - Use correct ValueSmall/ValueLarge error messages for under/over bounds Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- ruRU: ПРОЦЕНТИЛЬ.ВКЛ/ИСКЛ → ПЕРСЕНТИЛЬ.ВКЛ/ИСКЛ (match base name) - csCZ: QUARTIL → KVARTIL (proper Czech Excel name) - trTR: .DHL → .DAH for INC variants (Dahil, not typo) - index.ts: fix alphabetical export order (ModuloPlugin before PercentilePlugin) - PercentilePlugin: use ast.procedureName instead of hardcoded metadata key Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Autofix Details
Bugbot Autofix prepared fixes for both issues found in the latest run.
- ✅ Fixed: Wrong error message when percentile rank exceeds dataset size
- Split the combined
rank < 1 || rank > ncheck into two separate conditions sorank > nnow correctly returnsErrorMessage.ValueLargeinstead ofErrorMessage.ValueSmall.
- Split the combined
- ✅ Fixed: Russian PERCENTILE.INC/EXC translations use wrong root word
- Changed the Russian translations for PERCENTILE.INC and PERCENTILE.EXC from ПЕРСЕНТИЛЬ.ВКЛ/ПЕРСЕНТИЛЬ.ИСКЛ to ПРОЦЕНТИЛЬ.ВКЛ/ПРОЦЕНТИЛЬ.ИСКЛ to match official Microsoft Excel Russian locale names.
Or push these changes by commenting:
@cursor push 8d62452b48
Preview (8d62452b48)
diff --git a/src/i18n/languages/ruRU.ts b/src/i18n/languages/ruRU.ts
--- a/src/i18n/languages/ruRU.ts
+++ b/src/i18n/languages/ruRU.ts
@@ -369,8 +369,8 @@
LARGE: 'НАИБОЛЬШИЙ',
SMALL: 'НАИМЕНЬШИЙ',
PERCENTILE: 'ПЕРСЕНТИЛЬ',
- 'PERCENTILE.INC': 'ПЕРСЕНТИЛЬ.ВКЛ',
- 'PERCENTILE.EXC': 'ПЕРСЕНТИЛЬ.ИСКЛ',
+ 'PERCENTILE.INC': 'ПРОЦЕНТИЛЬ.ВКЛ',
+ 'PERCENTILE.EXC': 'ПРОЦЕНТИЛЬ.ИСКЛ',
QUARTILE: 'КВАРТИЛЬ',
'QUARTILE.INC': 'КВАРТИЛЬ.ВКЛ',
'QUARTILE.EXC': 'КВАРТИЛЬ.ИСКЛ',
diff --git a/src/interpreter/plugin/PercentilePlugin.ts b/src/interpreter/plugin/PercentilePlugin.ts
--- a/src/interpreter/plugin/PercentilePlugin.ts
+++ b/src/interpreter/plugin/PercentilePlugin.ts
@@ -34,9 +34,12 @@
function percentileExclusive(sortedVals: number[], k: number): number | CellError {
const n = sortedVals.length
const rank = k * (n + 1)
- if (rank < 1 || rank > n) {
+ if (rank < 1) {
return new CellError(ErrorType.NUM, ErrorMessage.ValueSmall)
}
+ if (rank > n) {
+ return new CellError(ErrorType.NUM, ErrorMessage.ValueLarge)
+ }
const intPart = Math.floor(rank)
const fraction = rank - intPart
if (intPart < n) {This Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.
…name) Microsoft uses different roots: legacy ПЕРСЕНТИЛЬ vs newer ПРОЦЕНТИЛЬ.ВКЛ/ИСКЛ. Confirmed via official ru-ru support.microsoft.com docs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
There are 3 total unresolved issues (including 1 from previous review).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 224d845. Configure here.
…docs) - csCZ: KVARTIL → QUARTIL (Czech Excel uses QUARTIL, not KVARTIL) - trTR: .DAH → .DHL (Turkish Excel uses .DHL, confirmed on support.microsoft.com/tr-tr) Our earlier code review incorrectly changed these. Official MS docs confirm the original translations were correct. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add @param/@returns tags to all public methods and module-level helpers - Rename intPart → lowerIndex for clarity in interpolation functions - Add inline comments explaining quart / 4 conversion - Improve class-level JSDoc to explain inclusive/exclusive distinction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
@marcin-kordas-hoc resolve the merge conflicts |
docs/guide/built-in-functions.md
Outdated
| | NORMSINV | Returns value of inverse normal distribution. | NORMSINV(P) | | ||
| | PEARSON | Returns the correlation coefficient between two data sets. | PEARSON(Data1, Data2) | | ||
| | PHI | Returns probability densitity of normal distribution. | PHI(X) | | ||
| | PERCENTILE | Returns the k-th percentile of values in a range. | PERCENTILE(Data, K) | |
There was a problem hiding this comment.
If this works the same as PERCENTILE.INC, it should have the same description
There was a problem hiding this comment.
Fixed in commit 17a65e5. PERCENTILE now has the same description as PERCENTILE.INC: "inclusive of 0 and 1".
docs/guide/built-in-functions.md
Outdated
| | POISSON | Returns density of Poisson distribution. | POISSON(X, Mean, Mode) | | ||
| | POISSON.DIST | Returns density of Poisson distribution. | POISSON.DIST(X, Mean, Mode) | | ||
| | POISSONDIST | Returns density of Poisson distribution. | POISSONDIST(X, Mean, Mode) | | ||
| | QUARTILE | Returns the quartile of a data set. | QUARTILE(Data, Quart) | |
There was a problem hiding this comment.
If this works the same as QUARTILE.INC, it should have the same description
There was a problem hiding this comment.
Fixed in commit 17a65e5. QUARTILE now has the same description as QUARTILE.INC: "based on inclusive percentile values".
| 'PERCENTILE': { | ||
| method: 'percentile', | ||
| parameters: [ | ||
| {argumentType: FunctionArgumentType.RANGE}, | ||
| {argumentType: FunctionArgumentType.NUMBER, minValue: 0, maxValue: 1}, | ||
| ], | ||
| }, | ||
| 'PERCENTILE.INC': { | ||
| method: 'percentile', | ||
| parameters: [ | ||
| {argumentType: FunctionArgumentType.RANGE}, | ||
| {argumentType: FunctionArgumentType.NUMBER, minValue: 0, maxValue: 1}, | ||
| ], | ||
| }, |
There was a problem hiding this comment.
If these 2 function work the same use FunctionPlugin.aliases
There was a problem hiding this comment.
Fixed in commit 17a65e5. PERCENTILE is now an alias for PERCENTILE.INC, and QUARTILE is an alias for QUARTILE.INC, using FunctionPlugin.aliases.
…review) - PERCENTILE is now an alias for PERCENTILE.INC - QUARTILE is now an alias for QUARTILE.INC - Docs: PERCENTILE and QUARTILE descriptions match their .INC variants Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ability Use ValueLarge for rank > n (upper bound) and ValueSmall for rank < 1 (lower bound) instead of generic ValueSmall for both. ErrorType stays NUM in both cases (Excel-compatible). Improves detailedError API for developers and AI agents per 2026 explainability priority.


Summary
PercentilePluginwith inclusive/exclusive interpolation helpersChanges
src/interpreter/plugin/PercentilePlugin.ts— new pluginsrc/interpreter/plugin/index.ts— export registrationsrc/i18n/languages/*.ts— all 17 languagesdocs/guide/built-in-functions.md— 6 new entries (alphabetical)CHANGELOG.md— added entryTest plan
npm run lintpassesnpm run compilepassesNote
Medium Risk
Adds new statistical function implementations in the interpreter, which can affect formula evaluation and error behavior for these functions. Scope is otherwise localized (docs/i18n/changelog), but correctness depends on interpolation and edge-case handling.
Overview
Introduces a new
PercentilePluginimplementingPERCENTILE.INC/PERCENTILE.EXCandQUARTILE.INC/QUARTILE.EXC, withPERCENTILEandQUARTILEas aliases to the inclusive variants.The implementation extracts numeric values from ranges, sorts them, computes inclusive/exclusive linear interpolation, and returns appropriate
#NUM!errors for out-of-range parameters or empty numeric inputs.Updates the built-in functions guide, adds an Unreleased changelog entry, and extends all language packs with translations for the new function names.
Reviewed by Cursor Bugbot for commit 6910f2c. Bugbot is set up for automated code reviews on this repo. Configure here.