The task
You have two variables: price, the original price of a product in dollars, and discount, a percentage. The program must print the discount as an amount of money, in dollars.
The example: with a price of 150 and a discount of 10, the answer is 15, because 10% of 150 dollars is 15 dollars. The lesson's variables are 70 and 15, so the program prints 15% of 70.
How a percentage becomes a calculation
"Percent" means "per hundred". A discount of 10 percent is 10 out of every 100, or the fraction 10 / 100. To find that part of a price, multiply the price by the fraction:
discount amount = price * discount / 100
150 * 10 / 100 = 1500 / 100 = 15
The variable discount holds 10, not 0.1, so the division by 100 is part of your code. If you skip it, you get 1500, which is the price multiplied by the percentage number and has no meaning as an amount of money.
Why the variables are float64
In Go, the type of a variable decides what / does. Between two integers it drops the fractional part. Between two float64 values it keeps it. The lesson declares both variables with the type float64 explicitly, so the division keeps its decimals.
The 100 in your expression is an untyped constant: a number written directly in the code that has no fixed type until it is used. In price * discount / 100 it takes the type of the other operand, float64, so Go does a decimal division. The expression doesn't need you to write 100.0.
To see the difference, compare the same calculation with integer variables:
var pi, di int = 70, 15
fmt.Println(pi * di / 100) // 10
fmt.Println(float64(pi) * float64(di) / 100) // 10.5
The first line computes 70 * 15 = 1050 and then divides by 100, but with integers it prints 10 and loses the 0.5. The second converts both values to float64 first and prints the exact amount, 10.5. Go refuses to mix the two types in one operation, so you convert deliberately: for instance, price * n with a float64 price and an int variable n does not compile and reports mismatched types float64 and int.
The lesson's exercise
- Read the two variables. Both are declared with
var name float64 = value, a different spelling of the same thing asname := valuewith a decimal literal like70.0. - Multiply the price by the discount and divide by 100. That gives the discount amount in dollars.
- Print the result with
fmt.Println.
var price float64 = 70.0
var discount float64 = 15.0
fmt.Println(price * discount / 100)
The program prints 10.5: 70 times 15 is 1050, and 1050 divided by 100 is 10.5. Ten dollars and fifty cents is the amount the customer saves.
Another way to write it
Multiplication and division have the same rank and run left to right, so price * discount / 100 multiplies first and then divides. Writing price * (discount / 100) prints the same 10.5 for these values, because with float64 the early division keeps its decimals. With int values the early division would give 0 for any discount below 100, so multiplying first is the safer habit.
Common mistakes and gotchas
- Leaving out the division by 100. The variable holds a percentage, not a fraction. Without
/ 100the result is 100 times too large. - Dividing the price by the discount.
price / discountanswers a different question (how many times the discount fits into the price) and has no connection to the saved amount. - Using integer variables. With
intvalues the result is cut off at the decimal point, as the 10 against 10.5 above shows. - Expecting exact decimals. A
float64stores numbers in binary, so some results show tiny errors. For example, with a price of 19.99 and a discount of 20,price * 20 / 100prints3.9979999999999993rather than 3.998. When the exact amount matters, as it does with real money, programs usually work in whole cents and use integers instead. - Printing text with the number. The lesson's tests expect only the amount.
fmt.Printlnwith extra words would change the output.
Key takeaways
- A percentage
pof an amount isamount * p / 100. - Division of two
float64values keeps decimals; division of twointvalues does not. - An untyped constant like
100adopts the type of the variable it is combined with. - Go never converts between
intandfloat64on its own, so write the conversion yourself.