> For the complete documentation index, see [llms.txt](https://kb.craftformswp.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kb.craftformswp.com/documentation/form-building/create-form/doing-math-in-formulas.md).

# Doing Math in Formulas

You can do calculations in a **Price Formula**, a **Smart Variable**, or a **Conditional Variable**. This page shows the symbols and functions you can use, in plain language. No coding needed.

***

#### The one thing to remember <a href="#the-one-thing-to-remember" id="the-one-thing-to-remember"></a>

On a calculator or in a spreadsheet, the **`^`** symbol usually means "to the power of".

**In CraftForms it does not.** If you type `^`, you will get a wrong price — the form won't show an error, it just quietly calculates the wrong number.

To raise something to a power, use **`**`** (two stars) or the **`pow()`** function instead.

| You want                | Don't write | Write this instead                |
| ----------------------- | ----------- | --------------------------------- |
| width to the power of 2 | `width^2` ❌ | `width**2` ✅ or `pow(width, 2)` ✅ |

If you type `^` by mistake, the editor will now show a yellow warning to remind you.

\
Everyday math

Use these just like you would on paper:

| To do this | Type | Example          |
| ---------- | ---- | ---------------- |
| Add        | `+`  | `width + 10`     |
| Subtract   | `-`  | `width - 5`      |
| Multiply   | `*`  | `width * height` |
| Divide     | `/`  | `total / 2`      |

**Tip:** use round brackets `( )` to group things so the math happens in the order you want — exactly like on a calculator. For example `(width + 10) * 2` adds first, then multiplies.

***

#### Powers and roots <a href="#powers-and-roots" id="powers-and-roots"></a>

| To do this        | Type one of these     | Example → result |
| ----------------- | --------------------- | ---------------- |
| Square (× itself) | `x**2` or `pow(x, 2)` | `5**2` → 25      |
| Cube              | `x**3` or `pow(x, 3)` | `2**3` → 8       |
| Square root       | `sqrt(x)` or `x**0.5` | `sqrt(16)` → 4   |
| Cube root         | `x**(1/3)`            | `27**(1/3)` → 3  |

**Tip:** when the power is a fraction, wrap it in brackets — `x**(1/3)`, not `x**1/3`.

***

#### Rounding numbers <a href="#rounding-numbers" id="rounding-numbers"></a>

Rounding numbers

| To do this              | Type          | Example → result         |
| ----------------------- | ------------- | ------------------------ |
| Round to a whole number | `round(x)`    | `round(4.6)` → 5         |
| Round to 2 decimals     | `round(x, 2)` | `round(4.567, 2)` → 4.57 |
| Always round up         | `ceil(x)`     | `ceil(4.1)` → 5          |
| Always round down       | `floor(x)`    | `floor(4.9)` → 4         |

***

#### Other handy functions <a href="#other-handy-functions" id="other-handy-functions"></a>

| To do this               | Type             | Example → result       |
| ------------------------ | ---------------- | ---------------------- |
| Smallest of some values  | `min(a, b, ...)` | `min(10, 4, 7)` → 4    |
| Largest of some values   | `max(a, b, ...)` | `max(10, 4, 7)` → 10   |
| Make a number positive   | `abs(x)`         | `abs(-5)` → 5          |
| Add up a list of numbers | `sum(list)`      | totals a set of values |

You'll see this list of functions next to every formula box, so you don't have to remember them.

***

#### Counting nights and days <a href="#counting-nights-and-days" id="counting-nights-and-days"></a>

For a booking with a check-in and a check-out date, **`count_nights(checkin, checkout)`** gives the number of nights between them. A [Booking Datepicker](/documentation/form-building/create-form/blocks/booking-datepicker-field.md) field named `stay` holds its dates as `stay.checkin` and `stay.checkout`.

The easiest way is to make a smart variable `nights` with `count_nights(stay.checkin, stay.checkout)`, then use `nights` in the price formula:

| To do this                            | Type                                                   | Example → result          |
| ------------------------------------- | ------------------------------------------------------ | ------------------------- |
| Price per night                       | `nights * 95`                                          | 4 nights → 380            |
| Price per day, counting both end days | `(count_nights(hire.checkin, hire.checkout) + 1) * 40` | Mon to Wed → 3 days → 120 |
| Charge at least 2 nights              | `max(nights, 2) * 95`                                  | 1 night → 190             |
| 10% off for a week or longer          | `nights >= 7 ? nights * 95 * 0.9 : nights * 95`        | 7 nights → 598.50         |
| A one-off cleaning fee on top         | `nights * 95 + 40`                                     | 4 nights → 420            |

`count_nights` gives 0 until both dates are picked, so the price starts at 0 (or at the fee alone) and fills in once the stay is chosen.

***

#### Using parts of a date <a href="#using-parts-of-a-date" id="using-parts-of-a-date"></a>

These pick one part out of a date or time, as a number. They work with a [Datepicker](/documentation/form-building/create-form/blocks/datepicker-field.md) field, with the dates of a Booking Datepicker (`stay.checkin`, `slot.date`) and with its times (`slot.time`).

| To get           | Type             | Example → result                        |
| ---------------- | ---------------- | --------------------------------------- |
| Day of the week  | `week_day(date)` | `week_day("2026-07-18")` → 6 (Saturday) |
| Day of the month | `day(date)`      | `day("2026-07-18")` → 18                |
| Month            | `month(date)`    | `month("2026-07-18")` → 7               |
| Year             | `year(date)`     | `year("2026-07-18")` → 2026             |
| Hour             | `hour(time)`     | `hour("18:30")` → 18                    |

Days of the week are numbered from **0 for Sunday** to **6 for Saturday**.

Some examples, with `event_date` a Datepicker field and `slot` a time-slot Booking Datepicker:

| To do this                                 | Type                                                                 |
| ------------------------------------------ | -------------------------------------------------------------------- |
| 50 extra on Saturdays and Sundays          | `(!is_empty(event_date) && week_day(event_date) in [0, 6]) ? 50 : 0` |
| A summer nightly rate (June to August)     | `month(stay.checkin) in [6, 7, 8] ? 120 : 90`                        |
| 15 extra for evening slots (6 pm or later) | `hour(slot.time) >= 18 ? 15 : 0`                                     |

**Tip:** these give 0 while the date is empty, and 0 is also Sunday. That's why the weekend example checks `!is_empty(event_date)` first. Otherwise every form would start with the weekend surcharge.

The summer rate uses the check-in month for the whole stay. For a stay that starts in August and ends in September, every night is charged at the summer rate.

***

#### Checking a date or time range <a href="#checking-a-date-or-time-range" id="checking-a-date-or-time-range"></a>

**`is_date_between(date, "from:to")`** is true when the date is in the range, the first and last day included. **`is_time_between(time, "from-to")`** does the same for times.

| To do this                         | Type                                                                 |
| ---------------------------------- | -------------------------------------------------------------------- |
| A holiday nightly rate             | `is_date_between(stay.checkin, "2026-12-20:2027-01-05") ? 150 : 100` |
| A new price from 1 January 2027 on | `is_date_between(event_date, "2027-01-01:") ? 80 : 70`               |
| An early-bird price up to 31 March | `is_date_between(event_date, ":2027-03-31") ? 60 : 75`               |
| A peak-hours surcharge             | `is_time_between(slot.time, "17:00-20:00") ? 10 : 0`                 |

Leave one side of the range empty for "from this date on" or "up to this date". Write the dates in the range as `YYYY-MM-DD`, like `2027-01-01`, or as `DD/MM/YYYY`, like `01/01/2027`. The field's own date can be in either format.

***

#### Counting chosen options <a href="#counting-chosen-options" id="counting-chosen-options"></a>

For a Checkboxes field, `extras` in a formula is the list of ticked options.

| To do this                             | Type                                    | Example → result     |
| -------------------------------------- | --------------------------------------- | -------------------- |
| How many options are ticked            | `count(extras)`                         | 3 ticked → 3         |
| 4 per ticked option                    | `count(extras) * 4`                     | 3 ticked → 12        |
| 10 off when 3 or more are ticked       | `count(extras) >= 3 ? -10 : 0`          | 3 ticked → -10       |
| 5 when one particular option is ticked | `includes("gift_wrap", extras) ? 5 : 0` | gift wrap ticked → 5 |

`count` gives 0 when nothing is ticked. In `includes`, use the option's **value**, not its label.

***

#### Counting words <a href="#counting-words" id="counting-words"></a>

**`words_count(text)`** counts the words in a text field, for a price per word such as a translation or an engraving.

| To do this                     | Type                                      | Example → result |
| ------------------------------ | ----------------------------------------- | ---------------- |
| 0.12 per word                  | `words_count(message) * 0.12`             | 250 words → 30   |
| First 20 words free, then 0.50 | `max(words_count(message) - 20, 0) * 0.5` | 30 words → 5     |

Every run of letters and digits counts as one word, so `don't` counts as 2 and a dash on its own counts as none.

***

#### Writing numbers correctly <a href="#writing-numbers-correctly" id="writing-numbers-correctly"></a>

A few small rules keep your formulas working:

* Put a **0 before the dot** for decimals: write `0.5`, not `.5`.
* **No commas** in big numbers: write `1500`, not `1,500`.
* **No currency signs**: write `20`, not `$20` or `€20`.
* Use field and variable **names on their own** (like `width` or `qty`) — CraftForms fills in the real value when the price is worked out.

#### Quick cheat sheet <a href="#quick-cheat-sheet" id="quick-cheat-sheet"></a>

| Instead of…   | Use…                  |
| ------------- | --------------------- |
| `x^2` (power) | `x**2` or `pow(x, 2)` |
| square root   | `sqrt(x)`             |
| `.5`          | `0.5`                 |
| `1,500`       | `1500`                |
| `$20`         | `20`                  |
