What you enter and what is computed
Enter one supplier price line per row: a label or SKU, the listed price, what that price is for (unit, pack or case), how many units are in a pack, how many packs are in a case, and optionally a currency code. Paste straight from a spreadsheet if you like; columns can be separated by tabs or commas. The tool divides each price by the number of single units it covers, shows the working, and sorts the lines by price per single unit, cheapest first, within each currency.
A price per unit is used as it is. A price per pack is divided by units per pack. A price per case is divided by units per pack times packs per case. You can also ask for the price of a number of units, for example 100 bottles.
- Example, invented: 19.99 per pack of 12 is 1999/1200 per unit, shown as 1.665833 rounded to six places; 120.00 per case of 6 packs of 12 is 5/3, shown as 1.666667. At two decimal places both would look like 1.67, but the exact comparison shows the first is the cheaper.
- Columns: label, price, unit | pack | case, units per pack, packs per case, currency. The last three may be left empty when they do not apply.
- Prices use a decimal point and no thousands separators; a decimal comma is rejected with an explanation rather than guessed.
Exact arithmetic, and why
Computers store most decimals such as 0.1 or 1.15 in binary floating point as a close approximation, not exactly. Python's documentation notes that numbers like 1.1 and 2.2 do not have exact representations in binary floating point, and that Fraction(1.1) is not Fraction(11, 10). Add rounding on top and two prices that are genuinely equal can compare as different, or a total built from rounded unit prices can disagree with the supplier's own amount by a few pence.
So this tool keeps every price as a fraction of whole numbers and compares lines by cross-multiplying, which cannot be wrong by a rounding error. Rounding appears only when a value is shown, half up, to the currency's minor-unit digits plus four more places (more, when the value would otherwise show as zero), and the exact fraction is printed next to it. Minor-unit digits come from the ISO 4217 list: two for pounds, dollars and euros, none for yen, three for Kuwaiti dinar.
- Prices with more decimals than the currency uses, such as 0.0125 per screw, are kept exactly and flagged, not rounded.
- Ties keep the order you entered them in.
- Lines in different currencies are ranked separately: no exchange rate is applied.
- A line that costs more than the cheapest is shown with its exact percentage difference to one decimal place; a difference under 0.1% is shown as 'less than 0.1%', never rounded up.
When the basis is unclear
A line is held back from the ranking, with a question to ask the supplier, when its pack size is missing or zero, when a case price has no packs-per-case figure, or when the price is zero (more likely a missing price than a free item). A line whose price basis is not one of unit (or each, item), pack or case is refused with the reason, not guessed; a word such as box or carton has to be mapped to pack or case first. A line is still calculated but flagged when it says per unit yet also gives a pack size greater than 1, because the price may really be for the pack. This is the failure the linked guide describes: a number accepted without its purchase unit.
Pack and case mean whatever the supplier says they mean. One supplier's case can hold a different number of packs from another's, and the same word can mean a carton, a box or a multipack. The tool cannot know the supplier's definition; it only divides the numbers you give it. Ask the supplier, or take the figures from their own price list.
- Pack sizes are whole numbers; weighed, measured or variable-size goods need a different calculation.
- Tax, freight, discounts, price breaks and minimum order quantities are not modelled.
- The W3C tabular data model says units are not part of a table's numbers by default, which is why the unit has to be written down.
Privacy and scope
Your price lines stay in this page. They are not sent anywhere, not stored and not added to the web address. Use invented or non-confidential figures if you prefer; the tool does not need supplier names.
If you want this done for you
This tool compares numbers you type; it does not read your supplier files. If someone reformats a supplier or ERP stock-and-price export by hand before each import, the first related outcome is a tested script that turns one named export layout into the exact import file your store accepts, rejecting rows it cannot convert with a reason. It does not decide which supplier's pack definition is right or which line to buy. If your supplier's price lists arrive as text-based PDFs, the second related outcome turns one list into a checked spreadsheet with a page-by-page row-count reconciliation and a list of rows it could not read with confidence. There is no separate outcome yet for a full supplier-feed import review; the collection listed with this tool describes the import checks in general. Scope and price are agreed before work; describe your layout with invented prices, pack sizes and the expected result, not private price lists.
Use the tool
Sources and limits
- Calculator implementation and tests Checked 2026-10-11.
- Prices are held as exact fractions of integers; lines are compared by cross-multiplication, never by rounded or floating-point values.
- Rounding happens only when a value is displayed, half up, and the exact value is shown beside it.
- SIX Group: ISO 4217 currency list (list one), published 2026-09-17 Checked 2026-10-11.
- Minor-unit digits used for display: 2 for GBP, USD, EUR and most listed currencies; 0 for JPY, KRW, CLP, ISK, UGX and VND; 3 for KWD, BHD, JOD, OMR and TND.
- Python documentation: fractions Checked 2026-10-11.
- Fraction(1.1) does not return Fraction(11, 10): a binary float is not exactly the decimal that was typed.
- Python documentation: decimal Checked 2026-10-11.
- Decimal numbers can be represented exactly, whereas numbers like 1.1 and 2.2 do not have exact representations in binary floating point.
- ROUND_HALF_UP is round to nearest with ties going away from zero.
- W3C: Model for Tabular Data and Metadata on the Web Checked 2026-10-11.
- Units of measure are not a built-in part of the tabular data model (section 4.5), so a number in a supplier file carries no unit unless it is stated separately.