# List of differences with other spreadsheets

<!--
The below dummy div uses a CSS class to alter the .page layout for the current page without any additional customization of VuePress.
It makes the page wider to accommodate large tables
-->
<div class="widePage"></div>

See a full list of differences between HyperFormula, Microsoft Excel, and Google Sheets.

**Contents:**

## General functionalities

| Functionality                                      | Examples                                                                  | HyperFormula                                                                                                                                                                                                                                                                                                                                                 | Google Sheets                                                                                                                  | Microsoft Excel                                                                                                                |
|----------------------------------------------------|---------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------|
| Dependency collection                              | A1:=IF(FALSE(), A1, 0)<br><br>ISREF(A1)                                   | Dependencies are collected during the parsing phase, which finds cycles that wouldn't appear in the evaluation.<br><br>`CYCLE` error for both examples.                                                                                                                                                                                                      | Dependencies are collected during evaluation.<br><br>`0` for both examples.                                                    | Same as Google Sheets.                                                                                                         |
| Named expressions and named ranges                 | SALARY:=$A$10 COST:=10*$B$5+100<br>PROFIT:=SALARY-COST<br>A1:=SALARY-COST | Only absolute addresses are allowed<br>(e.g., SALARY:= $A$10).<br><br>Named expressions can be global or scoped to one sheet only.<br><br>They can contain other named expressions.                                                                                                                                                                          | Named expressions are not available.<br><br>Named ranges can be used to create aliases for addresses and ranges.               | Named ranges and scoped named expressions are available.                                                                       |
| Named expression names                             | ProductPrice1:=42                                                         | A name must be distinctive from a cell reference (case-insensitive), so `ProductPrice1` is invalid. See [complete naming rules](named-expressions.md#name-rules).                                                                                                                                                                                            | A name that is a valid cell reference is allowed if the column address is at least 4-letter long, so `ProductPrice1` is valid. | A name that is a valid cell reference is allowed if the column address is at least 4-letter long, so `ProductPrice1` is valid. |
| Applying a scalar value to a function taking range | COLUMNS(A1)                                                               | `CellRangeExpected` error.                                                                                                                                                                                                                                                                                                                                   | Treats the element as length-1 range. Returns 1 for the example.                                                               | Same as Google Sheets.                                                                                                         |
| Coercion of explicit arguments                     | VARP(2, 3, 4, TRUE(), FALSE(), "1",)                                      | 1.9592, based on the behavior of Microsoft Excel.                                                                                                                                                                                                                                                                                                            | GoogleSheets implementation is not consistent with the standard (see also `VAR.S`, `STDEV.P`, and `STDEV.S` function.)         | 1.9592                                                                                                                         |
| Ranges created with `:`                            | A1:A2<br><br>A$1:$A$2<br><br>A:C<br><br>1:2<br><br>Sheet1!A1:A2           | Allowed ranges consist of two addresses (A1:B5), columns (A:C) or rows (3:5).<br>They cannot be mixed or contain named expressions.                                                                                                                                                                                                                          | Everything allowed.                                                                                                            | Same as Google Sheets.                                                                                                         |
| Formatting inside the TEXT function                | TEXT(A1,"dd-mm-yy")<br><br>TEXT(A1,"###.###”)                             | To support all date, time and currency formats, set [`stringifyDateTime`](compatibility-with-microsoft-excel.md#date-and-time-formats) and [`stringifyCurrency`](currency-handling.md) configuration options.                                                                                                                                                                                                                                                                                                  | A wide variety of options for string formatting is supported.                                                                  | Same as Google Sheets.                                                                                                         |
| Cell references inside inline arrays               | ={A1, A2}                                                                 | The array's value is calculated but not updated when the cells' values change.                                                                                                                                                                                                                                                                               | The array's value is calculated and updated when the cells' values change.                                                     | ERROR: invalid array                                                                                                           |
| SPLIT function                                     | =SPLIT("Lorem ipsum dolor", 0)                                            | This function works differently from Google Sheets version but should be sufficient to achieve the same functionality in most scenarios. Read SPLIT function description on [the Built-in Functions page](built-in-functions.md#text).                                                                                                                       | Different syntax and return value.                                                                                             | No such function.                                                                                                              |
| DATEVALUE function                                 | =DATEVALUE("25/02/1991")                                                  | Type of the returned value: `CellValueDetailedType.NUMBER_DATE` (compliant with the [OpenDocument](https://docs.oasis-open.org/office/OpenDocument/v1.3/os/part4-formula/OpenDocument-v1.3-os-part4-formula.html) standard)                                                                                                                                  | Cell auto-formatted as **regular number**                                                                                      | Cell auto-formatted as **regular number**                                                                                      |
| TIMEVALUE function                                 | =TIMEVALUE("14:31")                                                       | Type of the returned value: `CellValueDetailedType.NUMBER_TIME` (compliant with the [OpenDocument](https://docs.oasis-open.org/office/OpenDocument/v1.3/os/part4-formula/OpenDocument-v1.3-os-part4-formula.html) standard)                                                                                                                                  | Cell auto-formatted as **regular number**                                                                                      | Cell auto-formatted as **regular number**                                                                                      |
| EDATE function                                     | =EDATE(DATE(2019, 7, 31), 1)                                              | Type of the returned value: `CellValueDetailedType.NUMBER_DATE`. This is non-compliant with the [OpenDocument](https://docs.oasis-open.org/office/OpenDocument/v1.3/os/part4-formula/OpenDocument-v1.3-os-part4-formula.html) standard, which defines the return type as a Number, while describing it as a Date serial number through the function summary. | Cell auto-formatted as **date**                                                                                                | Cell auto-formatted as **regular number**                                                                                      |
| EOMONTH function                                   | =EOMONTH(DATE(2019, 7, 31), 1)                                            | Type of the returned value: `CellValueDetailedType.NUMBER_DATE`. This is non-compliant with the [OpenDocument](https://docs.oasis-open.org/office/OpenDocument/v1.3/os/part4-formula/OpenDocument-v1.3-os-part4-formula.html) standard, which defines the return type as a Number, while describing it as a Date serial number through the function summary. | Cell auto-formatted as **date**                                                                                                | Cell auto-formatted as **regular number**                                                                                      |
| Empty cells in lookup search                      | =XLOOKUP(3, A1:A4, A1:A4, "NF", 0, 2)<br>where A1:A4 = 1, 2, (empty), 3   | Empty cells are skipped during the search. A value that is present is found even when it sits past an interspersed empty cell (exact match is gap-independent), and approximate `MATCH`/`VLOOKUP`/`HLOOKUP`/`XLOOKUP` skip empty cells — but not empty strings — when finding the lower/upper bound. Returns `3`. On an all-empty range in a binary search mode, HyperFormula returns the `if_not_found` result (never row 1). | Skips empty cells in approximate search (parity with HyperFormula). | With binary search modes (`search_mode` ±2), a range with interspersed empty cells is not strictly sorted; per Excel's documentation the result may be invalid, so a value past an empty cell is not reliably found. On an all-empty range in a binary mode, Excel returns the first row's value. |

## Built-in functions

Some built-in functions are implemented differently than in Google Sheets or Microsoft Excel.

To remove the differences, create [custom implementations](custom-functions.md) of those functions.

| Function      | Example                                                        | HyperFormula | Google Sheets | Microsoft Excel |
|---------------|----------------------------------------------------------------|-------------:|--------------:|----------------:|
| TBILLEQ       | =TBILLEQ(0, 180, 1.9)                                          |      38.5278 |           NUM |             NUM |
| TBILLEQ       | =TBILLEQ(0, 180, 2)                                            |       0.0000 |           NUM |          0.0000 |
| TBILLEQ       | =TBILLEQ("1/2/2000", "31/1/2001", 0.1)                         |       0.1128 |         VALUE |           VALUE |
| TBILLEQ       | =TBILLEQ(0, 360, 0.1)                                          |       0.1127 |        0.1097 |          0.1097 |
| TBILLEQ       | =TBILLEQ(0, 365, 0.1)                                          |       0.1128 |        0.1098 |          0.1098 |
| GCD           | =GCD(1000000000000000000.0)                                    |          NUM |         1E+18 |             NUM |
| COMBIN        | =COMBIN(1030, 0)                                               |          NUM |           NUM |          1.0000 |
| RRI           | =RRI(1, -1, -1)                                                |       0.0000 |           NUM |          0.0000 |
| DAYS          | =DAYS(-1, 0)                                                   |          NUM |       -1.0000 |             NUM |
| DAYS          | =DAYS(0, -1)                                                   |          NUM |        1.0000 |             NUM |
| DATEDIF       | =DATEDIF(-1, 0, "Y")                                           |          NUM |        0.0000 |             NUM |
| RATE          | =RATE(12, -100, 400, 0, 1)                                     |      -1.0000 |           NUM |             NUM |
| PV            | =PV(-1, 0, 100, 400)                                           |          NUM |          -400 |             NUM |
| LCMP          | =LCM(1000000, 1000001, 1000002, 1000003)                       |          NUM |   5.00003E+23 |             NUM |
| TBILLPRICE    | =TBILLPRICE(0, 180, 1.9)                                       |       5.0000 |           NUM |          5.0000 |
| TBILLPRICE    | =TBILLPRICE(0, 180, 2)                                         |       0.0000 |           NUM |          0.0000 |
| NPV           | =NPV(1, TRUE(), 1)                                             |       0.7500 |        0.5000 |          0.7500 |
| NPV           | =NPV(1,B1) where B1 = true                                     |       0.5000 |        0.0000 |          0.0000 |
| POISSON.DIST  | =POISSON.DIST(-0.01, 0, FALSE())                               |          NUM |        1.0000 |             NUM |
| POISSON.DIST  | =POISSON.DIST(0, -0.01, FALSE())                               |          NUM |           NUM |          1.0101 |
| DB            | =DB(1000000, 100000, 6, 7, 7)                                  |   15845.1000 |           NUM |      15845.0985 |
| BETA.DIST     | =BETA.DIST(1, 2, 3)                                            |          N/A |        1.0000 |             NUM |
| BETA.DIST     | =BETA.DIST(0, 1, 1, FALSE())                                   |          NUM |        0.0000 |             NUM |
| BETA.DIST     | =BETA.DIST(0.6, 1, 1, FALSE(), 0.6, 0.7)                       |          NUM |        0.0000 |          0.0000 |
| BETA.DIST     | =BETA.DIST(0.7, 1, 1, FALSE(), 0.6, 0.7)                       |          NUM |        0.0000 |          0.0000 |
| GAMMA         | =GAMMA(-2.5)                                                   |      -0.9453 |           NUM |         -0.9453 |
| BINOM.DIST    | =BINOM.DIST(0.5, 0.4, 1,   FALSE())                            |          N/A |           NUM |          1.0000 |
| NEGBINOM.DIST | =NEGBINOM.DIST(0, 1, 0, FALSE())                               |       0.0000 |           N/A |             NUM |
| NEGBINOM.DIST | =NEGBINOM.DIST(0, 1, 1, FALSE())                               |       1.0000 |           N/A |             NUM |
| T.INV         | =T.INV(0, 1)                                                   |          NUM |           NUM |           DIV/0 |
| BETA.INV      | =BETA.INV(1, 1, 1)                                             |       1.0000 |        1.0000 |             NUM |
| WEIBULL.DIST  | =WEIBULL.DIST(0, 1, 1, FALSE())                                |       1.0000 |        1.0000 |          0.0000 |
| HYPGEOM.DIST  | =HYPGEOM.DIST(12.1, 12, 20, 40, TRUE())                        |          NUM |           N/A |          1.0000 |
| HYPGEOM.DIST  | =HYPGEOM.DIST(12.1, 20, 12, 40, TRUE())                        |          NUM |           N/A |          1.0000 |
| HYPGEOM.DIST  | =HYPGEOM.DIST(1, 2, 3, 4)                                      |          N/A |        0.5000 |             NUM |
| HYPGEOM.DIST  | =HYPGEOM.DIST(4, 12, 20, 40, TRUE())                           |       0.1504 |           N/A |          0.1504 |
| TDIST         | =TDIST(0, 1, 1.5)                                              |          NUM |        0.5000 |          0.5000 |
| T.INV.2T      | =T.INV.2T(0, 1)                                                |          NUM |           NUM |           DIV/0 |
| T.DIST        | =T.DIST(1, 0.9, FALSE())                                       |          NUM |           NUM |           DIV/0 |
| AVEDEV        | =AVEDEV(TRUE(), FALSE())                                       |       0.4444 |        0.0000 |          0.4444 |
| LARGE         | =LARGE(TRUE(), 1)                                              |          NUM |           NUM |          1.0000 |
| COUNTA        | =COUNTA(1,)                                                    |       2.0000 |        1.0000 |          2.0000 |
| XNPV          | =XNPV(-0.9, A2:D2, A3:D3)<br>where 2nd and 3rd row: 1, 2, 3, 4 |      10.1272 |   10.12716959 |             NUM |
| SKEW          | =SKEW(TRUE(), FALSE())                                         |       1.7321 |         DIV/0 |          1.7321 |
| HARMEAN       | =HARMEAN(TRUE(), "4")                                          |       1.6000 |        4.0000 |          1.6000 |
| GEOMEAN       | =GEOMEAN(TRUE(), "4")                                          |       2.0000 |        4.0000 |          2.0000 |
| CHISQ.TEST    | =CHISQ.TEST(A1:C2, A1:F1)                                      |          N/A |           N/A |           DIV/0 |
| BINOM.INV     | =BINOM.INV(1, 0.8, 0.2)                                        |       0.0000 |        1.0000 |          1.0000 |
| BINOM.INV     | =BINOM.INV(-0.001, 0.5, 0.5)                                   |          NUM |        0.0000 |             NUM |
| BINOM.INV     | =BINOM.INV(10, 0, 0.5)                                         |       0.0000 |           NUM |             NUM |
| BINOM.INV     | =BINOM.INV(10, 1, 0.5)                                         |      10.0000 |           NUM |             NUM |
| DEVSQ         | =DEVSQ(A2, A3)                                                 |       0.0000 |        0.0000 |             NUM |
| NORMSDIST     | =NORMSDIST(0, TRUE())                                          |          0.5 |  Wrong number |    Wrong number |
| ADDRESS       | =ADDRESS(1,1,4, TRUE(), "")                                    |          !A1 |         ''!A1 |             !A1 |
| SEQUENCE      | =SEQUENCE(0)                                                   |        VALUE |           N/A |           CALC  |
| INT           | =INT(-8.9)                                                     |           -8 |            -9 |              -9 |
| MOD           | =MOD(-10, 3)                                                   |           -1 |             2 |               2 |
| ISEVEN        | =ISEVEN(2.5)                                                   |        FALSE |          TRUE |            TRUE |
| ISODD         | =ISODD(3.5)                                                    |        FALSE |          TRUE |            TRUE |
| CEILING.MATH  | =CEILING.MATH(-4.3, 2, 2)                                      |           -4 |            -6 |              -6 |
| FLOOR.MATH    | =FLOOR.MATH(-4.7, 2, 2)                                        |           -6 |            -4 |              -4 |

A few of the rows above share a root cause worth stating once:

- **Rounding toward zero, not down.** `INT` discards the fractional part rather than rounding toward negative infinity, so it differs from Excel and Google Sheets for negative input only. `ROUNDDOWN`/`ROUNDUP` are unaffected — they are defined in terms of zero in all three.
- **`MOD` takes the sign of the dividend.** Excel and Google Sheets return a result with the sign of the *divisor*.
- **`ISEVEN`/`ISODD` do not truncate.** They test the remainder of the value as given, so a value with a fractional part returns `FALSE` from *both*. Excel and Google Sheets truncate to an integer first, so exactly one of the two is always `TRUE`.
- **`CEILING.MATH`/`FLOOR.MATH` honour only `mode` = 1.** Excel and Google Sheets switch the negative-number rounding direction for any non-zero `mode`.