Math, operators and integer division
Kotlin's arithmetic looks exactly like school maths until one rule bites: dividing two whole numbers throws the fraction away. Learn the operators, the order they run in, and the trap that has bitten every programmer alive.
Seven sweets, two friends
You have seven sweets and two friends. How many does each friend get?
Three. And there is one left over, because you cannot cut a sweet in half without an argument.
Every child works this out without being taught. Kotlin does exactly the same thing, and every programmer is surprised by it once. Here is the line that surprises them:
println(7 / 2)That prints 3. Not 3.5. Not 4. Just 3.
By the end of this lesson you will know precisely why, and you will never be caught by it again.
Think of a vending machine that only takes whole coins.
You feed it a five-pound note for a £2 drink. It gives you two drinks and £1 change. It does not give you two and a half drinks, because half a drink is not a thing the machine can produce.
is that machine. Ask a whole number to be split by another whole number and Kotlin hands back a whole number — how many fit — and keeps the leftovers separately. The leftovers are what % is for.
The five arithmetic operators
An is a symbol that does something to values. Kotlin's arithmetic set is short:
| Operator | Does | 7 and 2 give |
|---|---|---|
+ | Adds | 9 |
- | Subtracts | 5 |
* | Multiplies | 14 |
/ | Divides | 3 |
% | Remainder | 1 |
The first three hold no surprises. The last two are the lesson.
Why / behaves like that
Kotlin's rule is simple once you say it out loud:
divided by
Intgives anInt.
There is no room in an Int for a decimal point, so the fractional part is thrown away. Kotlin does not round — it truncates, meaning it chops towards zero:
1println(7 / 2) // 3
2println(9 / 10) // 0
3println(-7 / 2) // -3Look at 9 / 10 for a second. Ten does not fit into nine at all, so the answer is zero. That line has silently ruined many a percentage calculation.
And -7 / 2 is -3, not -4. Truncating towards zero means the answer moves up for negatives. Kotlin never rounds down and never rounds to nearest — it always chops.
Getting the decimal answer
Make at least one side a and Kotlin gives you a Double back:
1println(7 / 2.0) // 3.5
2println(7.0 / 2) // 3.5
3val a = 7
4val b = 2
5println(a.toDouble() / b) // 3.5That third form is the one you will use in real code, because your values usually arrive as Int from somewhere else.
The most common version of this bug hides inside a longer sum:
1val done = 3
2val total = 4
3val percent = done / total * 100percent is 0. Kotlin does 3 / 4 first, which is 0, then multiplies zero by a hundred. Fix it by converting first: done.toDouble() / total * 100, which gives 75.0.
The remainder operator
% gives what is left over. It is far more useful than it sounds:
1println(7 % 2) // 1
2println(10 % 5) // 0
3println(13 % 5) // 3Two everyday jobs for it:
- Is this number even?
n % 2 == 0is true for even numbers. - Wrap a counter round. If you have six dice faces and a counter that keeps climbing,
counter % 6always lands between 0 and 5.
The name to know is , though most people just say "mod".
Order of operations
Kotlin follows the same order you learnt at school: multiply and divide before add and subtract, brackets first.
1println(2 + 3 * 4) // 14, not 20
2println((2 + 3) * 4) // 20When a line gets long, add brackets even where they are not strictly needed. They cost nothing and they tell the next reader what you meant.
^ is not "to the power of" in Kotlin. For squaring, just multiply: n * n. For anything larger, Math.pow(2.0, 10.0) does the job and returns a Double.
Shorthand for changing a var
These four lines all add ten to a score, and all of them are common in real code:
1var score = 0
2score = score + 10
3score += 10
4score+++= means "add this to what is already there". The family is +=, -=, *=, /= and %=. score++ is a special shorthand for score += 1, used constantly in loops.
All of these change the value, so they only work on a . Try them on a and you get Val cannot be reassigned.
The whole lesson in nine lines
- Open Pocket Studio, tap Projects, open KotlinLab, and open
Lab.kt. - Clear the inside of
mainand type in the program from the walkthrough above. - Tap Run. The Output panel should read
3,1,3.5,11— one per line. - Add one line before the closing bracket:
println(9 / 10). Run it. It prints0. Sit with that for a moment; it is the single most expensive line in this lesson. - Change it to
println(9.0 / 10)and run again. Now it prints0.9. - Add
println(-7 / 2). Run. It prints-3, because chopping moves towards zero. - Last one: change
var score = 0toval score = 0and run. Read the error, then change it back. Shorthand like+=still counts as changing a name.
= produced a decimal, but the name on the left was declared Int. Usually one value in the sum was a Double.Double, or finish the sum with .toInt() if you genuinely want the fraction thrown away.+=, -= or ++ on a name declared with val. All three change the value, which val forbids.var. If it should not change, the error has found a real bug in the line that modifies it.Double but wrote a whole number: val rate: Double = 5.5.0. Kotlin will not silently promote the literal for you, because being explicit here prevents worse confusion later.Int by zero while running. This one is not caught at build time — it crashes the program.if (friends > 0) { ... }. Note that dividing a Double by zero does not crash — it produces Infinity, which is its own kind of nasty surprise.+ at the end of a line, or an empty pair of brackets.+, -, *, / and % needs a value on both sides.- The are
+,-,*,/and%, and they follow the school order: brackets, then multiply and divide, then add and subtract. - The fraction is chopped off, not rounded, and it chops towards zero — so
-7 / 2is-3. - Convert one side with
.toDouble()when you want the decimal answer, and convert before the rest of the sum, not after. %gives the : handy for "is it even?" and for wrapping counters round.+=,-=and++are shorthand for changing a value, and only work on a .- Next: you have values and you can do sums with them. Time to make the program choose what to do —
ifandelse.