---
title: "Rounding rules"
description: "Every rounding mode with a worked example, plus what happens in currencies that have no decimal places."
url: "https://maksut.net/price-anchor/docs/rounding/"
language: "en-US"
datePublished: "2026-08-02T00:35:15+00:00"
dateModified: "2026-10-10T08:40:00+00:00"
---

# Rounding rules

Rounding is applied last, after the rate and markup, and always respects your store currency’s decimal places — two for USD or EUR, zero for JPY, three for KWD.

## Modes in the free plugin

| Mode | Behaviour | 1234.567 becomes |
| --- | --- | --- |
| No rounding | The calculated value, untouched | 1234.567 |
| Currency decimals | Rounded to the store currency’s decimal places | 1234.57 |
| Round up to a whole number | Always up | 1235 |
| Round down to a whole number | Always down | 1234 |
| Round to the nearest whole number | Standard rounding | 1235 |
| Charm pricing — ends in .99 | Up to the next value ending in .99 | 1234.99 |

## How charm .99 actually behaves

The contract is that the result is **never below** the calculated price. Selling a penny below the anchored price is a margin loss on every single unit of every product priced at a round figure, and that is exactly the bug a naive implementation produces.

- 298.20 becomes 298.99 — up, as expected.
- 299.00 becomes **299.99**, not 298.99. A naive `ceil(price) - 0.01` would have gone down here.
- A price that is already exactly x.99 stays at x.99.

In a currency with fewer than two decimal places, “.99” cannot be expressed at all. Rather than silently produce a price the store cannot represent, charm mode falls back to rounding up to a whole unit, which still honours the never-below contract.

## Choosing a mode

- **Currency decimals** is the safe default. It produces honest, exact conversions.
- **Round up to a whole number** suits markets where prices with visible decimals look unfinished, and it never rounds against you.
- **Charm .99** suits consumer retail where price psychology matters.
- **Round down** is the only mode that can round against your margin. Use it deliberately, and be aware it compounds with a thin markup.
- **No rounding** is mostly useful while testing, when you want to see the raw arithmetic.

## Pro rounding modes

Pro adds charm endings of .9, .90 and .999, rounding to multiples of 5, 10, 50 or 100, and a configurable minimum increment. These are registered through a strategy registry rather than by extending the free plugin’s enum, because a PHP enum cannot be extended.

If Pro is deactivated while a Pro-only rounding mode is selected, the free plugin falls back to no rounding. Prices stay valid and no product is left unpriced — the number simply stops being charmed.
