What arithmetic operators do
Kotlin has five arithmetic operators, and they work on numbers the way you expect from school mathematics: + adds, - subtracts, * multiplies, / divides and % gives the remainder of a division. Each one takes a value on its left and a value on its right, and each can be used with plain numbers, with variables, or with a mix of both.
val a = 2
val b = 3
println(a + b) // 5
println(a - b) // -1
println(a * 5) // 10
println(2 * a * b) // 12
When Kotlin sees a variable in an expression, it replaces the variable with its current value. Doing arithmetic on a variable never changes the variable. After println(a + b), both a and b still hold 2 and 3. The only way to change what a variable holds is to assign to it with = (and only a var allows that; a val is fixed once set).
Division needs care
Division is the operator that surprises beginners. In Kotlin, the type of the result follows the types of the operands. If both sides are integers (Int), the result is an integer too, and the fractional part is thrown away:
val a = 2
val b = 3
println(20 / 3) // 6
println(b / a) // 1
Integer division truncates toward zero, so -7 / 2 is -3, not -4. If you want the fractional part, at least one side must be a Double. You can write a decimal literal such as 2.0, or convert a value with toDouble():
val a = 2
val b = 3
println(7.toDouble() / 3) // 2.3333333333333335
println(b / a.toDouble()) // 1.5
println(7 / 2.0) // 3.5
A common trap is converting too late. (7 / 2).toDouble() divides two integers first, gets 3, and only then converts it to 3.0. Convert one operand before the division, as in the examples above.
The remainder operator
The % operator gives what is left over after a division. 20 % 3 is 2, because 3 fits into 20 six times with 2 left. Together, / and % on integers satisfy (a / b) * b + a % b == a. The result of % takes the sign of the left operand, so -7 % 3 is -1.
Int is 32 bits
An Int holds values from -2147483648 to 2147483647. If a calculation goes past that range, Kotlin does not warn you: the result wraps around.
val big = 2147483647
println(big + 1) // -2147483648
println(big.toLong() + 1) // 2147483648
For the small numbers in this lesson that never matters, but it is worth knowing before you multiply large values. Use Long when results can get big.
The exercise
The variable price holds the cost of one product, 83. Andy buys 4 products at that price and one bag for 15, and the task is to print the total he pays.
- Multiply the quantity by the price. Four products at
priceeach cost4 * price. - Add the bag. The bag costs a fixed 15, so it is added to the product cost.
- Print the whole expression.
printlnaccepts any expression, so there is no need for an extra variable.
Because * is evaluated before +, the multiplication happens first without any parentheses.
val price: Int = 83
println(4 * price + 15)
The output is 347: 4 times 83 is 332, and 332 plus 15 is 347. The type annotation : Int is optional, since Kotlin would infer Int from the literal 83. Writing it just makes the type visible.
Common mistakes
- Expecting a decimal from integer division.
3 / 2is 1. Use3 / 2.0or3.toDouble() / 2for 1.5. - Dividing by zero. Integer division or remainder by zero throws an
ArithmeticExceptionwith the message/ by zero. WithDoublevalues,1.0 / 0printsInfinityinstead. - Assuming a variable changed. Writing
price * 4on its own line computes a value and discards it;pricekeeps its old value. - Looking for a power operator. Kotlin has no operator for powers. Library functions do that job.
Key takeaways
+,-,*,/and%work with numbers and with variables holding numbers.- Arithmetic never changes a variable; only assignment does.
- Dividing two
Intvalues drops the fractional part; make one side aDoubleto keep it. Intoverflow wraps silently, so reach forLongwhen numbers can grow large.