Skip to content
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

## [Unreleased]

### Added

- Added the `PERMUT`, `PERMUTATIONA` and `BINOM.DIST.RANGE` functions. [#1790](https://github.com/handsontable/hyperformula/pull/1790)

## [3.5.0] - 2026-10-09

### Added
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/languages/csCZ.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@ const dictionary: RawTranslationPackage = {
FACTDOUBLE: 'FACTDOUBLE',
COMBIN: 'KOMBINACE',
COMBINA: 'COMBINA',
PERMUT: 'PERMUT',
PERMUTATIONA: 'PERMUTATIONA',
GCD: 'GCD',
LCM: 'LCM',
MROUND: 'MROUND',
Expand Down Expand Up @@ -314,6 +316,7 @@ const dictionary: RawTranslationPackage = {
BETAINV: 'BETAINV',
'BINOM.DIST': 'BINOM.DIST',
BINOMDIST: 'BINOMDIST',
'BINOM.DIST.RANGE': 'BINOM.DIST.RANGE',
'BINOM.INV': 'BINOM.INV',
BESSELI: 'BESSELI',
BESSELJ: 'BESSELJ',
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/languages/daDK.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@ const dictionary: RawTranslationPackage = {
FACTDOUBLE: 'DOBBELT.FAKULTET',
COMBIN: 'KOMBIN',
COMBINA: 'KOMBINA',
PERMUT: 'PERMUT',
PERMUTATIONA: 'PERMUTATIONA',
GCD: 'STØRSTE.FÆLLES.DIVISOR',
LCM: 'MINDSTE.FÆLLES.MULTIPLUM',
MROUND: 'MAFRUND',
Expand Down Expand Up @@ -314,6 +316,7 @@ const dictionary: RawTranslationPackage = {
BETAINV: 'BETAINV',
'BINOM.DIST': 'BINOMIAL.FORDELING',
BINOMDIST: 'BINOMIALFORDELING',
'BINOM.DIST.RANGE': 'BINOM.DIST.RANGE',
'BINOM.INV': 'BINOMIAL.INV',
BESSELI: 'BESSELI',
BESSELJ: 'BESSELJ',
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/languages/deDE.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@ const dictionary: RawTranslationPackage = {
FACTDOUBLE: 'ZWEIFAKULTÄT',
COMBIN: 'KOMBINATIONEN',
COMBINA: 'KOMBINA',
PERMUT: 'PERMUT',
PERMUTATIONA: 'PERMUTATIONA',
GCD: 'GGT',
LCM: 'KGV',
MROUND: 'VRUNDEN',
Expand Down Expand Up @@ -314,6 +316,7 @@ const dictionary: RawTranslationPackage = {
BETAINV: 'BETAINV',
'BINOM.DIST': 'BINOM.VERT',
BINOMDIST: 'BINOMVERT',
'BINOM.DIST.RANGE': 'BINOM.DIST.RANGE',
'BINOM.INV': 'BINOM.INV',
BESSELI: 'BESSELI',
BESSELJ: 'BESSELJ',
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/languages/enGB.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,8 @@ const dictionary: RawTranslationPackage = {
FACTDOUBLE: 'FACTDOUBLE',
COMBIN: 'COMBIN',
COMBINA: 'COMBINA',
PERMUT: 'PERMUT',
PERMUTATIONA: 'PERMUTATIONA',
GCD: 'GCD',
LCM: 'LCM',
MROUND: 'MROUND',
Expand All @@ -314,6 +316,7 @@ const dictionary: RawTranslationPackage = {
BETAINV: 'BETAINV',
'BINOM.DIST': 'BINOM.DIST',
BINOMDIST: 'BINOMDIST',
'BINOM.DIST.RANGE': 'BINOM.DIST.RANGE',
'BINOM.INV': 'BINOM.INV',
BESSELI: 'BESSELI',
BESSELJ: 'BESSELJ',
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/languages/esES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@ export const dictionary: RawTranslationPackage = {
FACTDOUBLE: 'FACT.DOBLE',
COMBIN: 'COMBINAT',
COMBINA: 'COMBINA',
PERMUT: 'PERMUT',
PERMUTATIONA: 'PERMUTATIONA',
GCD: 'M.C.D',
LCM: 'M.C.M',
MROUND: 'REDOND.MULT',
Expand Down Expand Up @@ -314,6 +316,7 @@ export const dictionary: RawTranslationPackage = {
BETAINV: 'DISTR.BETA.INV',
'BINOM.DIST': 'DISTR.BINOM.N',
BINOMDIST: 'DISTR.BINOM',
'BINOM.DIST.RANGE': 'BINOM.DIST.RANGE',
'BINOM.INV': 'INV.BINOM',
BESSELI: 'BESSELI',
BESSELJ: 'BESSELJ',
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/languages/fiFI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@ const dictionary: RawTranslationPackage = {
FACTDOUBLE: 'KERTOMA.OSA',
COMBIN: 'KOMBINAATIO',
COMBINA: 'KOMBINAATIOA',
PERMUT: 'PERMUT',
PERMUTATIONA: 'PERMUTATIONA',
GCD: 'SUURIN.YHT.TEKIJÄ',
LCM: 'PIENIN.YHT.JAETTAVA',
MROUND: 'PYÖRISTÄ.KERR',
Expand Down Expand Up @@ -314,6 +316,7 @@ const dictionary: RawTranslationPackage = {
BETAINV: 'BEETAJAKAUMA.KÄÄNT',
'BINOM.DIST': 'BINOMI.JAKAUMA',
BINOMDIST: 'BINOMIJAKAUMA',
'BINOM.DIST.RANGE': 'BINOM.DIST.RANGE',
'BINOM.INV': 'BINOMIJAKAUMA.KÄÄNT',
BESSELI: 'BESSELI',
BESSELJ: 'BESSELJ',
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/languages/frFR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@ const dictionary: RawTranslationPackage = {
FACTDOUBLE: 'FACTDOUBLE',
COMBIN: 'COMBIN',
COMBINA: 'COMBINA',
PERMUT: 'PERMUT',
PERMUTATIONA: 'PERMUTATIONA',
GCD: 'PGCD',
LCM: 'PPCM',
MROUND: 'ARRONDI.AU.MULTIPLE',
Expand Down Expand Up @@ -314,6 +316,7 @@ const dictionary: RawTranslationPackage = {
BETAINV: 'BETA.INVERSE',
'BINOM.DIST': 'LOI.BINOMIALE.N',
BINOMDIST: 'LOI.BINOMIALE',
'BINOM.DIST.RANGE': 'BINOM.DIST.RANGE',
'BINOM.INV': 'LOI.BINOMIALE.INVERSE',
BESSELI: 'BESSELI',
BESSELJ: 'BESSELJ',
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/languages/huHU.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@ const dictionary: RawTranslationPackage = {
FACTDOUBLE: 'FAKTDUPLA',
COMBIN: 'KOMBINÁCIÓK',
COMBINA: 'KOMBINÁCIÓK.ISM',
PERMUT: 'PERMUT',
PERMUTATIONA: 'PERMUTATIONA',
GCD: 'LKO',
LCM: 'LKT',
MROUND: 'TÖBBSZ.KEREKÍT',
Expand Down Expand Up @@ -314,6 +316,7 @@ const dictionary: RawTranslationPackage = {
BETAINV: 'INVERZ.BÉTA',
'BINOM.DIST': 'BINOM.ELOSZL',
BINOMDIST: 'BINOM.ELOSZLÁS',
'BINOM.DIST.RANGE': 'BINOM.DIST.RANGE',
'BINOM.INV': 'BINOM.INVERZ',
BESSELI: 'BESSELI',
BESSELJ: 'BESSELJ',
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/languages/idID.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,8 @@ const dictionary: RawTranslationPackage = {
FACTDOUBLE: 'FAKTOR.GANDA',
COMBIN: 'KOMBINASI',
COMBINA: 'KOMBINASIA',
PERMUT: 'PERMUT',
PERMUTATIONA: 'PERMUTATIONA',
GCD: 'FPB',
LCM: 'KPK',
MROUND: 'BULATKAN.MULTIPLE',
Expand All @@ -314,6 +316,7 @@ const dictionary: RawTranslationPackage = {
BETAINV: 'BETAINV',
'BINOM.DIST': 'BINOM.DIST',
BINOMDIST: 'BINOMDIST',
'BINOM.DIST.RANGE': 'BINOM.DIST.RANGE',
'BINOM.INV': 'BINOM.INV',
BESSELI: 'BESSELI',
BESSELJ: 'BESSELJ',
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/languages/itIT.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@ const dictionary: RawTranslationPackage = {
FACTDOUBLE: 'FATT.DOPPIO',
COMBIN: 'COMBINAZIONE',
COMBINA: 'COMBINAZIONE.VALORI',
PERMUT: 'PERMUT',
PERMUTATIONA: 'PERMUTATIONA',
GCD: 'MCD',
LCM: 'MCM',
MROUND: 'ARROTONDA.MULTIPLO',
Expand Down Expand Up @@ -314,6 +316,7 @@ const dictionary: RawTranslationPackage = {
BETAINV: 'INV.BETA',
'BINOM.DIST': 'DISTRIB.BINOM.N',
BINOMDIST: 'DISTRIB.BINOM',
'BINOM.DIST.RANGE': 'BINOM.DIST.RANGE',
'BINOM.INV': 'INV.BINOM',
BESSELI: 'BESSEL.I',
BESSELJ: 'BESSEL.J',
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/languages/nbNO.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@ const dictionary: RawTranslationPackage = {
FACTDOUBLE: 'DOBBELFAKT',
COMBIN: 'KOMBINASJON',
COMBINA: 'KOMBINASJONA',
PERMUT: 'PERMUT',
PERMUTATIONA: 'PERMUTATIONA',
GCD: 'SFF',
LCM: 'MFM',
MROUND: 'MRUND',
Expand Down Expand Up @@ -314,6 +316,7 @@ const dictionary: RawTranslationPackage = {
BETAINV: 'INVERS.BETA.FORDELING',
'BINOM.DIST': 'BINOM.FORDELING.N',
BINOMDIST: 'BINOM.FORDELING',
'BINOM.DIST.RANGE': 'BINOM.DIST.RANGE',
'BINOM.INV': 'BINOM.INV',
BESSELI: 'BESSELI',
BESSELJ: 'BESSELJ',
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/languages/nlNL.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@ const dictionary: RawTranslationPackage = {
FACTDOUBLE: 'DUBBELE.FACULTEIT',
COMBIN: 'COMBINATIES',
COMBINA: 'COMBIN.A',
PERMUT: 'PERMUT',
PERMUTATIONA: 'PERMUTATIONA',
GCD: 'GGD',
LCM: 'KGV',
MROUND: 'AFRONDEN.N.VEELVOUD',
Expand Down Expand Up @@ -314,6 +316,7 @@ const dictionary: RawTranslationPackage = {
BETAINV: 'BETAINV',
'BINOM.DIST': 'BINOM.VERD',
BINOMDIST: 'BINOMIALE.VERD',
'BINOM.DIST.RANGE': 'BINOM.DIST.RANGE',
'BINOM.INV': 'BINOMIALE.INV',
BESSELI: 'BESSEL.I',
BESSELJ: 'BESSEL.J',
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/languages/plPL.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@ const dictionary: RawTranslationPackage = {
FACTDOUBLE: 'SILNIA.DWUKR',
COMBIN: 'KOMBINACJE',
COMBINA: 'KOMBINACJE.A',
PERMUT: 'PERMUT',
PERMUTATIONA: 'PERMUTATIONA',
GCD: 'NAJW.WSP.DZIEL',
LCM: 'NAJMN.WSP.WIEL',
MROUND: 'ZAOKR.DO.WIELOKR',
Expand Down Expand Up @@ -314,6 +316,7 @@ const dictionary: RawTranslationPackage = {
BETAINV: 'ROZKŁAD.BETA.ODW',
'BINOM.DIST': 'ROZKŁ.DWUM',
BINOMDIST: 'ROZKŁAD.DWUM',
'BINOM.DIST.RANGE': 'BINOM.DIST.RANGE',
'BINOM.INV': 'ROZKŁ.DWUM.ODWR',
BESSELI: 'BESSEL.I',
BESSELJ: 'BESSEL.J',
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/languages/ptPT.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@ const dictionary: RawTranslationPackage = {
FACTDOUBLE: 'FATDUPLO',
COMBIN: 'COMBIN',
COMBINA: 'COMBINA',
PERMUT: 'PERMUT',
PERMUTATIONA: 'PERMUTATIONA',
GCD: 'MDC',
LCM: 'MMC',
MROUND: 'MARRED',
Expand Down Expand Up @@ -314,6 +316,7 @@ const dictionary: RawTranslationPackage = {
BETAINV: 'BETA.ACUM.INV',
'BINOM.DIST': 'DISTR.BINOM',
BINOMDIST: 'DISTRBINOM',
'BINOM.DIST.RANGE': 'BINOM.DIST.RANGE',
'BINOM.INV': 'INV.BINOM',
BESSELI: 'BESSELI',
BESSELJ: 'BESSELJ',
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/languages/ruRU.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@ const dictionary: RawTranslationPackage = {
FACTDOUBLE: 'ДВФАКТР',
COMBIN: 'ЧИСЛКОМБ',
COMBINA: 'ЧИСЛКОМБА',
PERMUT: 'PERMUT',
PERMUTATIONA: 'PERMUTATIONA',
GCD: 'НОД',
LCM: 'НОК',
MROUND: 'ОКРУГЛТ',
Expand Down Expand Up @@ -314,6 +316,7 @@ const dictionary: RawTranslationPackage = {
BETAINV: 'БЕТАОБР',
'BINOM.DIST': 'БИНОМ.РАСП',
BINOMDIST: 'БИНОМРАСП',
'BINOM.DIST.RANGE': 'BINOM.DIST.RANGE',
'BINOM.INV': 'БИНОМ.ОБР',
BESSELI: 'БЕССЕЛЬ.I',
BESSELJ: 'БЕССЕЛЬ.J',
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/languages/svSE.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@ const dictionary: RawTranslationPackage = {
FACTDOUBLE: 'DUBBELFAKULTET',
COMBIN: 'KOMBIN',
COMBINA: 'COMBINA',
PERMUT: 'PERMUT',
PERMUTATIONA: 'PERMUTATIONA',
GCD: 'SGD',
LCM: 'MGM',
MROUND: 'MAVRUNDA',
Expand Down Expand Up @@ -314,6 +316,7 @@ const dictionary: RawTranslationPackage = {
BETAINV: 'BETAINV',
'BINOM.DIST': 'BINOM.FÖRD',
BINOMDIST: 'BINOMFÖRD',
'BINOM.DIST.RANGE': 'BINOM.DIST.RANGE',
'BINOM.INV': 'BINOM.INV',
BESSELI: 'BESSELI',
BESSELJ: 'BESSELJ',
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/languages/trTR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@ const dictionary: RawTranslationPackage = {
FACTDOUBLE: 'ÇİFTFAKTÖR',
COMBIN: 'KOMBİNASYON',
COMBINA: 'KOMBİNASYONA',
PERMUT: 'PERMUT',
PERMUTATIONA: 'PERMUTATIONA',
GCD: 'OBEB',
LCM: 'OKEK',
MROUND: 'KYUVARLA',
Expand Down Expand Up @@ -314,6 +316,7 @@ const dictionary: RawTranslationPackage = {
BETAINV: 'BETATERS',
'BINOM.DIST': 'BİNOM.DAĞ',
BINOMDIST: 'BİNOMDAĞ',
'BINOM.DIST.RANGE': 'BINOM.DIST.RANGE',
'BINOM.INV': 'BİNOM.TERS',
BESSELI: 'BESSELI',
BESSELJ: 'BESSELJ',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,20 @@ export const MATH_AND_TRIGONOMETRY_DOCS: Record<string, FunctionDoc> = {
documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html',
examples: ['=COMBINA(4, 3)', '=COMBINA(10, 2)'],
},
PERMUT: {
category: 'Math and trigonometry',
shortDescription: 'Returns the number of permutations of a given number of items chosen from a set (without repetitions).',
parameters: [{name: 'number', description: 'The total number of items; truncated to an integer.'}, {name: 'number_chosen', description: 'The number of items in each permutation; truncated to an integer and must not exceed number.'}],
documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html',
examples: ['=PERMUT(5, 2)', '=PERMUT(10, 3)'],
},
PERMUTATIONA: {
category: 'Math and trigonometry',
shortDescription: 'Returns the number of permutations of a given number of items chosen from a set (with repetitions).',
parameters: [{name: 'number', description: 'The total number of items; truncated to an integer.'}, {name: 'number_chosen', description: 'The number of items in each permutation, where an item may repeat; truncated to an integer.'}],
documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html',
examples: ['=PERMUTATIONA(3, 2)', '=PERMUTATIONA(2, 10)'],
},
COS: {
category: 'Math and trigonometry',
shortDescription: 'Returns the cosine of the given angle (in radians).',
Expand Down
7 changes: 7 additions & 0 deletions src/interpreter/functionMetadata/categories/statistical.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ export const STATISTICAL_DOCS: Record<string, FunctionDoc> = {
documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html',
examples: ['=BINOM.DIST(3, 10, 0.5, FALSE())', '=BINOM.DIST(3, 10, 0.5, TRUE())'],
},
'BINOM.DIST.RANGE': {
category: 'Statistical',
shortDescription: 'Returns the probability of a trial result using a binomial distribution over a range of successes.',
parameters: [{name: 'trials', description: 'The total number of independent trials; truncated to an integer.'}, {name: 'probability_s', description: 'The probability of success on a single trial, between 0 and 1.'}, {name: 'number_s', description: 'The lower bound of the number of successes; truncated to an integer.'}, {name: 'number_s2', description: 'The upper bound of the number of successes; truncated to an integer. Defaults to number_s when omitted.'}],
documentationUrl: 'https://hyperformula.handsontable.com/docs/guide/built-in-functions.html',
examples: ['=BINOM.DIST.RANGE(10, 0.5, 5)', '=BINOM.DIST.RANGE(10, 0.5, 3, 7)'],
},
'BINOM.INV': {
category: 'Statistical',
shortDescription: 'Returns inverse binomial distribution value.',
Expand Down
40 changes: 40 additions & 0 deletions src/interpreter/plugin/MathPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,20 @@ export class MathPlugin extends FunctionPlugin implements FunctionPluginTypechec
{argumentType: FunctionArgumentType.NUMBER, minValue: 0}
]
},
'PERMUT': {
method: 'permut',
parameters: [
{argumentType: FunctionArgumentType.NUMBER, minValue: 0},
{argumentType: FunctionArgumentType.NUMBER, minValue: 0}
]
},
'PERMUTATIONA': {
method: 'permutationa',
parameters: [
{argumentType: FunctionArgumentType.NUMBER, minValue: 0},
{argumentType: FunctionArgumentType.NUMBER, minValue: 0}
]
},
'GCD': {
method: 'gcd',
parameters: [
Expand Down Expand Up @@ -167,6 +181,32 @@ export class MathPlugin extends FunctionPlugin implements FunctionPluginTypechec
)
}

public permut(ast: ProcedureAst, state: InterpreterState): InterpreterValue {
return this.runFunction(ast.args, state, this.metadata('PERMUT'),
(n: number, k: number) => {
n = Math.trunc(n)
k = Math.trunc(k)
if (k > n) {
return new CellError(ErrorType.NUM, ErrorMessage.WrongOrder)
}
let ret = 1
for (let i = 0; i < k && Number.isFinite(ret); i++) {
ret *= n - i
}
return Number.isFinite(ret) ? ret : new CellError(ErrorType.NUM, ErrorMessage.NaN)
}
)
}

public permutationa(ast: ProcedureAst, state: InterpreterState): InterpreterValue {
return this.runFunction(ast.args, state, this.metadata('PERMUTATIONA'),
(n: number, k: number) => {
const ret = Math.pow(Math.trunc(n), Math.trunc(k))
return Number.isFinite(ret) ? ret : new CellError(ErrorType.NUM, ErrorMessage.NaN)
}
)
}

public gcd(ast: ProcedureAst, state: InterpreterState): InterpreterValue {
return this.runFunction(ast.args, state, this.metadata('GCD'),
(...args: RawInterpreterValue[]) => {
Expand Down
Loading
Loading