The task
Two variables describe a sale: price, the original price of a product in dollars, and discount, a percentage. The program must print the price the customer pays after the discount is taken off.
In the example, the price is 150 and the discount is 10. Ten percent of 150 is 15, and 150 minus 15 is 135, so the answer is 135. The lesson's own variables hold 70 and 15.
Two ways to think about it
You can reach the final price in two steps or in one.
Subtract the discount amount
First find how many dollars the discount is worth, then subtract it from the price:
discount amount = price * discount / 100
final price = price - discount amount
This mirrors the way the example is explained, and it is easy to follow, but it needs the discount amount twice in your head.
Multiply by the fraction you keep
If 10 percent comes off, the customer pays the remaining 90 percent. That remaining share is 100 - discount out of 100:
final price = price * (100 - discount) / 100
150 * (100 - 10) / 100 = 150 * 90 / 100 = 135
This version is a single expression, and the lesson uses it. The two forms always give the same result in maths; the second is shorter and has one fewer step to get wrong.
Types: why the division keeps its decimals
The starting code is:
price := 70.0
discount := 15.0
A short declaration with := gives the variable the type of the value on the right. A literal with a decimal point, like 70.0, is a float64, so both variables are float64. Without the .0, price := 70 would create an int, and everything would change, because / on two integers drops the fractional part.
Here is the difference on the lesson's values, with int variables:
p, d := 70, 15
fmt.Println(p * (100 - d) / 100) // 59
The multiplication gives 70 * 85 = 5950, and the integer division by 100 gives 59, losing the 0.5. With float64 variables the result is 59.5. The number 100 in the expression needs no suffix: it is an untyped constant, so it takes the type of the variable it is combined with.
The lesson's exercise
- Work out the share to keep.
100 - discountis 85 when the discount is 15. The parentheses are required: they make the subtraction run before the multiplication, which would otherwise go first. - Multiply the price by that share.
price * (100 - discount)is 70 * 85 = 5950. - Divide by 100 to turn the percentage into a fraction. Since all the values are
float64, the division returns 59.5. - Print the result with
fmt.Println.
price := 70.0
discount := 15.0
fmt.Println(price * (100 - discount) / 100)
The program prints 59.5. As a check, 15% of 70 is 10.5, and 70 minus 10.5 is 59.5.
You can also write price - price * discount / 100, which is the two-step idea in one line, and it gives the same 59.5 here. Choose whichever reads more clearly to you.
Common mistakes and gotchas
- Missing parentheses.
price * 100 - discount / 100is read as(price * 100) - (discount / 100), which is 6999.85. The subtraction must be wrapped in parentheses so it runs first. - Printing the discount instead of the final price.
price * discount / 100is the saving (10.5), not what remains to pay. - Using integer variables. With
intvalues the answer is cut to a whole number, as the 59 above shows. - Mixing
intandfloat64. Go does not convert automatically. Multiplying afloat64variable by anintvariable does not compile. Convert explicitly, such asfloat64(n). - Treating
float64as exact. Decimal results can show tiny errors such as3.9979999999999993in other calculations. For real money, programs often store whole cents in integers. This lesson's values happen to print cleanly.
Key takeaways
- After a discount of
dpercent, the customer paysprice * (100 - d) / 100. - A literal such as
70.0makes afloat64variable with:=; a literal such as70makes anint. - Parentheses make the subtraction run before the multiplication and division.
- Division of two
float64values keeps decimals.