Skip to content

Commit 1852159

Browse files
marcin-kordas-hocclaudesequba
authored
Add PERCENTILE and QUARTILE function families (#1650)
## Summary - Implement 6 new functions: PERCENTILE, PERCENTILE.INC, PERCENTILE.EXC, QUARTILE, QUARTILE.INC, QUARTILE.EXC - New `PercentilePlugin` with inclusive/exclusive interpolation helpers - i18n translations for all 17 languages (verified against Excel function translator) - CHANGELOG entry and built-in-functions.md updated ## Changes - `src/interpreter/plugin/PercentilePlugin.ts` — new plugin - `src/interpreter/plugin/index.ts` — export registration - `src/i18n/languages/*.ts` — all 17 languages - `docs/guide/built-in-functions.md` — 6 new entries (alphabetical) - `CHANGELOG.md` — added entry ## Test plan - [ ] 57 unit tests in hyperformula-tests (function-percentile.spec.ts) - [ ] Excel validation workbook (107 cases) — open in Excel 365 desktop, verify all PASS - [ ] `npm run lint` passes - [ ] `npm run compile` passes - [ ] CI green <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Introduces new statistical function implementations and aliases in the interpreter; main risk is correctness/edge-case parity with spreadsheet semantics and potential impacts to function translation tables. > > **Overview** > Adds `PERCENTILE`/`QUARTILE` function families, including `.INC` and `.EXC` variants, via a new `PercentilePlugin` that computes percentiles/quartiles with linear interpolation and appropriate `#NUM!` error handling for out-of-range inputs. > > Registers the plugin export, adds function aliases (`PERCENTILE`→`PERCENTILE.INC`, `QUARTILE`→`QUARTILE.INC`), and updates built-in function documentation, changelog, and all language packs to include translations for the new function names. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 7172a52. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Kuba Sekowski <jakub.sekowski@handsontable.com>
1 parent 736235e commit 1852159

20 files changed

Lines changed: 329 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
99

1010
### Added
1111

12+
- Added new functions: PERCENTILE, PERCENTILE.INC, PERCENTILE.EXC, QUARTILE, QUARTILE.INC, QUARTILE.EXC. [#1650](https://github.com/handsontable/hyperformula/pull/1650)
1213
- Added `maxPendingLazyTransformations` configuration option to control memory usage by limiting accumulated transformations before cleanup. [#1629](https://github.com/handsontable/hyperformula/issues/1629)
1314
- Added a new function: TEXTJOIN. [#1640](https://github.com/handsontable/hyperformula/pull/1640)
1415
- Added a new function: SEQUENCE. [#1645](https://github.com/handsontable/hyperformula/pull/1645)

docs/guide/built-in-functions.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,9 +436,15 @@ Total number of functions: **{{ $page.functionsCount }}**
436436
| NORMSINV | Returns value of inverse normal distribution. | NORMSINV(P) |
437437
| PEARSON | Returns the correlation coefficient between two data sets. | PEARSON(Data1, Data2) |
438438
| PHI | Returns probability densitity of normal distribution. | PHI(X) |
439+
| PERCENTILE | Returns the k-th percentile of values in a range, inclusive of 0 and 1. | PERCENTILE(Data, K) |
440+
| PERCENTILE.EXC | Returns the k-th percentile of values in a range, exclusive of 0 and 1. | PERCENTILE.EXC(Data, K) |
441+
| PERCENTILE.INC | Returns the k-th percentile of values in a range, inclusive of 0 and 1. | PERCENTILE.INC(Data, K) |
439442
| POISSON | Returns density of Poisson distribution. | POISSON(X, Mean, Mode) |
440443
| POISSON.DIST | Returns density of Poisson distribution. | POISSON.DIST(X, Mean, Mode) |
441444
| POISSONDIST | Returns density of Poisson distribution. | POISSONDIST(X, Mean, Mode) |
445+
| QUARTILE | Returns the quartile of a data set, based on inclusive percentile values. | QUARTILE(Data, Quart) |
446+
| QUARTILE.EXC | Returns the quartile of a data set, based on exclusive percentile values. | QUARTILE.EXC(Data, Quart) |
447+
| QUARTILE.INC | Returns the quartile of a data set, based on inclusive percentile values. | QUARTILE.INC(Data, Quart) |
442448
| RSQ | Returns the squared correlation coefficient between two data sets. | RSQ(Data1, Data2) |
443449
| SKEW | Returns skeweness of a sample. | SKEW(Number1, Number2, ...NumberN) |
444450
| SKEW.P | Returns skeweness of a population. | SKEW.P(Number1, Number2, ...NumberN) |

src/i18n/languages/csCZ.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,12 @@ const dictionary: RawTranslationPackage = {
370370
IMTAN: 'IMTAN',
371371
LARGE: 'LARGE',
372372
SMALL: 'SMALL',
373+
PERCENTILE: 'PERCENTIL',
374+
'PERCENTILE.INC': 'PERCENTIL.INC',
375+
'PERCENTILE.EXC': 'PERCENTIL.EXC',
376+
QUARTILE: 'QUARTIL',
377+
'QUARTILE.INC': 'QUARTIL.INC',
378+
'QUARTILE.EXC': 'QUARTIL.EXC',
373379
AVEDEV: 'PRŮMODCHYLKA',
374380
CONFIDENCE: 'CONFIDENCE',
375381
'CONFIDENCE.NORM': 'CONFIDENCE.NORM',

src/i18n/languages/daDK.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,12 @@ const dictionary: RawTranslationPackage = {
370370
IMTAN: 'IMAGTAN',
371371
LARGE: 'STØRSTE',
372372
SMALL: 'MINDSTE',
373+
PERCENTILE: 'FRAKTIL',
374+
'PERCENTILE.INC': 'FRAKTIL.MEDTAG',
375+
'PERCENTILE.EXC': 'FRAKTIL.UDELAD',
376+
QUARTILE: 'KVARTIL',
377+
'QUARTILE.INC': 'KVARTIL.MEDTAG',
378+
'QUARTILE.EXC': 'KVARTIL.UDELAD',
373379
AVEDEV: 'MAD',
374380
CONFIDENCE: 'KONFIDENSINTERVAL',
375381
'CONFIDENCE.NORM': 'KONFIDENS.NORM',

src/i18n/languages/deDE.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,12 @@ const dictionary: RawTranslationPackage = {
370370
IMTAN: 'IMATAN',
371371
LARGE: 'KGRÖSSTE',
372372
SMALL: 'KKLEINSTE',
373+
PERCENTILE: 'QUANTIL',
374+
'PERCENTILE.INC': 'QUANTIL.INKL',
375+
'PERCENTILE.EXC': 'QUANTIL.EXKL',
376+
QUARTILE: 'QUARTILE',
377+
'QUARTILE.INC': 'QUARTILE.INKL',
378+
'QUARTILE.EXC': 'QUARTILE.EXKL',
373379
AVEDEV: 'MITTELABW',
374380
CONFIDENCE: 'KONFIDENZ',
375381
'CONFIDENCE.NORM': 'KONFIDENZ.NORM',

src/i18n/languages/enGB.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,12 @@ const dictionary: RawTranslationPackage = {
370370
IMTAN: 'IMTAN',
371371
LARGE: 'LARGE',
372372
SMALL: 'SMALL',
373+
PERCENTILE: 'PERCENTILE',
374+
'PERCENTILE.INC': 'PERCENTILE.INC',
375+
'PERCENTILE.EXC': 'PERCENTILE.EXC',
376+
QUARTILE: 'QUARTILE',
377+
'QUARTILE.INC': 'QUARTILE.INC',
378+
'QUARTILE.EXC': 'QUARTILE.EXC',
373379
AVEDEV: 'AVEDEV',
374380
CONFIDENCE: 'CONFIDENCE',
375381
'CONFIDENCE.NORM': 'CONFIDENCE.NORM',

src/i18n/languages/esES.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,12 @@ export const dictionary: RawTranslationPackage = {
370370
IMTAN: 'IMTAN',
371371
LARGE: 'K.ESIMO.MAYOR',
372372
SMALL: 'K.ESIMO.MENOR',
373+
PERCENTILE: 'PERCENTIL',
374+
'PERCENTILE.INC': 'PERCENTIL.INC',
375+
'PERCENTILE.EXC': 'PERCENTIL.EXC',
376+
QUARTILE: 'CUARTIL',
377+
'QUARTILE.INC': 'CUARTIL.INC',
378+
'QUARTILE.EXC': 'CUARTIL.EXC',
373379
AVEDEV: 'DESVPROM',
374380
CONFIDENCE: 'INTERVALO.CONFIANZA',
375381
'CONFIDENCE.NORM': 'INTERVALO.CONFIANZA.NORM',

src/i18n/languages/fiFI.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,12 @@ const dictionary: RawTranslationPackage = {
370370
IMTAN: 'KOMPLEKSI.TAN',
371371
LARGE: 'SUURI',
372372
SMALL: 'PIENI',
373+
PERCENTILE: 'PROSENTTIPISTE',
374+
'PERCENTILE.INC': 'PROSENTTIPISTE.SIS',
375+
'PERCENTILE.EXC': 'PROSENTTIPISTE.ULK',
376+
QUARTILE: 'NELJÄNNES',
377+
'QUARTILE.INC': 'NELJÄNNES.SIS',
378+
'QUARTILE.EXC': 'NELJÄNNES.ULK',
373379
AVEDEV: 'KESKIPOIKKEAMA',
374380
CONFIDENCE: 'LUOTTAMUSVÄLI',
375381
'CONFIDENCE.NORM': 'LUOTTAMUSVÄLI.NORM',

src/i18n/languages/frFR.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,12 @@ const dictionary: RawTranslationPackage = {
370370
IMTAN: 'COMPLEXE.TAN',
371371
LARGE: 'GRANDE.VALEUR',
372372
SMALL: 'PETITE.VALEUR',
373+
PERCENTILE: 'CENTILE',
374+
'PERCENTILE.INC': 'CENTILE.INCLURE',
375+
'PERCENTILE.EXC': 'CENTILE.EXCLURE',
376+
QUARTILE: 'QUARTILE',
377+
'QUARTILE.INC': 'QUARTILE.INCLURE',
378+
'QUARTILE.EXC': 'QUARTILE.EXCLURE',
373379
AVEDEV: 'ECART.MOYEN',
374380
CONFIDENCE: 'INTERVALLE.CONFIANCE',
375381
'CONFIDENCE.NORM': 'INTERVALLE.CONFIANCE.NORMAL',

src/i18n/languages/huHU.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,12 @@ const dictionary: RawTranslationPackage = {
370370
IMTAN: 'KÉPZ.TAN',
371371
LARGE: 'NAGY',
372372
SMALL: 'KICSI',
373+
PERCENTILE: 'PERCENTILIS',
374+
'PERCENTILE.INC': 'PERCENTILIS.TARTALMAZ',
375+
'PERCENTILE.EXC': 'PERCENTILIS.KIZÁR',
376+
QUARTILE: 'KVARTILIS',
377+
'QUARTILE.INC': 'KVARTILIS.TARTALMAZ',
378+
'QUARTILE.EXC': 'KVARTILIS.KIZÁR',
373379
AVEDEV: 'ÁTL.ELTÉRÉS',
374380
CONFIDENCE: 'MEGBÍZHATÓSÁG',
375381
'CONFIDENCE.NORM': 'MEGBÍZHATÓSÁG.NORM',

0 commit comments

Comments
 (0)