This original example rounds the discount to the nearest cent, with a half-cent rounded up, and subtracts that rounded discount from the original price in cents. It gives $3.00 in savings and a $16.99 sale price. Together, those amounts equal $19.99.
The prices and rates here are fictional calculation inputs. Taxes, shipping, fees, promotion eligibility, and actual offers are unknown and excluded. The sale price is the remaining item price under the declared calculation policy, rather than a checkout total.

Keep the price, rate, and policy in one record
The basic relationship is discount amount = original price × discount rate, followed by sale price = original price − discount amount. OpenStax explains this original-price basis in its discount applications section.
For a reader to check the cents, the record needs more than those two formulas:
| Field | Worked entry |
|---|---|
| Currency | USD in this example |
| Original price | $19.99, or 1999 cents |
| Percent off | 15%, entered as 15 |
| Raw discount | $19.99 × 15/100 = $2.9985 |
| Declared rounding | Round discount to cents, half up |
| Displayed discount | $3.00, or 300 cents |
| Remaining sale price | 1999 − 300 = 1699 cents, or $16.99 |
| Reconciliation | 300 + 1699 = 1999 cents |
The raw value explains the arithmetic. The rounded value explains the two amounts you report. Keep both visible, especially when comparing a generated tool with a worked record.
This policy is a design choice for the example. Do not assume it matches a retailer's calculation rules. Before interpreting an actual price, confirm its currency, original-price basis, permitted discounts, and rounding method.
Subtract the rounded discount once
The local example parses $19.99 as exactly 1999 cents. Calculate the discount from that price and the entered rate without prematurely rounding the rate or an intermediate result. Round the discount once, then subtract it using integer cents.
That sequence makes the reconciliation simple: original cents = discount cents + sale-price cents. If you independently round a savings figure and a remaining-price figure, you risk making the displayed parts disagree with the displayed original under some rounding rules.
Use the two endpoints as checks:
| Fictional price and rate | Savings | Remaining price |
|---|---|---|
| $100.00 at 20% off | $20.00 | $80.00 |
| $19.99 at 0% off | $0.00 | $19.99 |
| $19.99 at 100% off | $19.99 | $0.00 |
| $0.00 at 15% off | $0.00 | $0.00 |
Zero is a supplied price or rate in these rows. An empty price or rate field is missing input and should not be treated as zero.
Apply a second discount to the remaining price
“20% off, then another 10% off” does not mean 30% off when the second percentage applies to the remainder. For the fictional $100 example:
| Stage | Price used as this stage's basis | Rate | Rounded savings | Remainder |
|---|---|---|---|---|
| First | $100.00 | 20% | $20.00 | $80.00 |
| Second | $80.00 | 10% | $8.00 | $72.00 |
Total savings are $20 + $8 = $28, or 28% of the original $100. The second $8 is ten percent of $80, not ten percent of the original $100.
Keep each stage's basis in the record. The remaining share in this exact whole-dollar example is 0.80 × 0.90 = 0.72. Adding the discount rates would ignore the changing basis.
Reversing these particular rates gives $100 → $90 → $72. The final amount is the same in this example, but the intermediate prices and stage savings differ. Cent rounding and actual promotion rules need their own checks; do not generalize this example into a claim about coupon order or eligibility.
An optional second-discount switch should therefore mean only “apply this supplied rate to the first stage's remaining price.” Leave it off for a single discount. When it is on, require a valid second rate and show both stages. That is a mathematical illustration, not verification that two offers can be combined.
Reject incomplete inputs and remove the old answer
The example accepts prices from 0 through 1000000 with up to two fractional digits, and percentage rates from 0 through 100 with up to six fractional digits. Use a US decimal point. Currency and rate fields have different limits: $19.999 is outside the price scope, while a rate of 15.125% is within the rate scope.
Reject blank, negative, out-of-range, nonfinite, comma-formatted, and scientific-notation entries. Explain which field needs correction. These are tool-scope choices, not a universal definition of all possible discounts.
After a valid $19.99/15% calculation, changing the rate to 115 must remove the old $16.99 result. An error beside an unchanged sale price invites the reader to use the previous answer for the new input. Clear results when inputs or the second-stage switch change, then calculate only after all active fields validate.
Copy this prompt for the complete discount tool
Create an original self-contained offline HTML discount calculator
in US English, with all necessary local code in one file.
Use USD for the example. No network calls, accounts, storage,
imports, exports, checkout, real promotions or financial advice.
Inputs: original price, first percent-off rate, and an optional
second-stage switch with a required second rate when enabled.
Enter 15 for 15%. Do not accept typed currency or percent symbols.
Price scope: 0..1000000 with up to two fractional digits.
Rate scope: 0..100 with up to six fractional digits.
Use US dot-decimal notation. Reject blank, negative, out-of-range,
nonfinite, commas, scientific notation and excess fractional digits.
Parse the price into exact integer cents and the rate into an exact
rational value. Declare this policy prominently: calculate the raw
discount, round the discount once to cents using half up, then
subtract rounded discount cents from the stage's price in cents.
Do not calculate money from an already rounded rate or display.
Show original price, entered rate, raw discount derivation, rounded
savings, remaining sale price, and a cent reconciliation.
Original cents must equal savings cents plus remaining cents.
For stage two, use stage one's remaining price as the new basis,
apply the same rounding policy and show both stages separately.
Show total savings relative to the original price; if that price is
zero, label the effective savings percentage undefined rather than
dividing by zero. Still show the valid zero-dollar amounts.
Worked fictional checks:
$19.99 at 15%: raw $2.9985, rounded savings $3.00,
sale $16.99; 1999 = 300 + 1699 cents.
$100 at 20%: savings $20, remainder $80.
Then 10% of $80: savings $8, remainder $72.
Combined savings $28 = 28% of original $100, not 30%.
Reverse these example rates: $100 -> $90 -> $72;
intermediate stage records differ. Do not promise all rounded
calculations or real coupon rules are order-independent.
0% leaves the price unchanged; 100% leaves zero.
$0 at 15% produces zero savings and zero remainder.
Clear old results on every active input/switch change. Invalid
active input produces an accessible error and no stale result.
Include labeled keyboard-operable controls, visible focus and a
readable narrow-screen layout. State that tax, shipping, fees,
actual offer terms and eligibility are unknown and excluded.
Include a plain-text worked record and manual checks for endpoints,
second-stage basis, cents and clearing invalid input. Return the
complete file; do not claim tests ran unless actually executed.
Check the generated tool's cent reconciliation and staged basis before using its result. Retain the original price, entered rates, rounding policy, and each remaining price in your own calculation record.
Keep the cents and stage basis visible in NOS
NOS can save and render prepared HTML. An HTML discount companion can display the $2.9985 raw calculation beside the $3.00 savings and $16.99 remainder, then show exactly which price a second discount uses.
Check any local calculation controls against the worked cases, and keep the native calculation record available. The declared item-price calculation still leaves taxes, fees, and actual offer terms to be confirmed. Explore NOS.