skip to content

Arithmetic & Comparison Operators

Arithmetic works as expected with integer division truncating, and the comparison operators are sugar over compareTo(). The Kotlin-specific twist is that bitwise operations are infix functions — shl, and, or, xor, inv — rather than symbols.

part ofKotlinoverview, primer and where to startread it →
on this pageshow

questions

5

What does 7 / 2 evaluate to in Kotlin, and how do you get a fractional result instead?

level: juniorimportance: must knowfreq 70%

answer

  1. Int / Int = Int, truncates toward zero
  2. Promote one operand: 7.0 / 2
  3. val d: Double = 7 / 2 is still 3.0
  4. No implicit widening — use .toDouble()
  5. BigDecimal for money

basics

~10 s

7 / 2 is 3, because dividing two whole numbers throws away the part after the decimal point. To get 3.5, make at least one number a decimal, like 7.0 / 2.

solid answer

~40 s

Division of two integers performs integer (truncating toward zero) division, so 7 / 2 == 3 and -7 / 2 == -3. The result type is the integer type of the operands. To get a floating-point result you must promote at least one operand to a Double or Float: 7.0 / 2, 7 / 2.0, or 7.toDouble() / 2 all yield 3.5. Kotlin never auto-widens Int to Double for you, so writing val x: Double = 7 / 2 still computes 3 in Int arithmetic first and then assigns 3.0 — a classic bug. The % operator gives the remainder (7 % 2 == 1). For exact decimal math (money) use BigDecimal instead of Double.

code

kotlin · 8 lines
kotlin
fun main() {
    println(7 / 2)            // 3
    println(7.0 / 2)          // 3.5
    println(7 / 2.0)          // 3.5
    val bug: Double = 7 / 2   // 3.0  <-- computed as Int first
    println(bug)
    println(7 % 2)            // 1
}

go deeper

for a junior

Knows 7 / 2 == 3 and that you promote an operand to a Double for 3.5.

for a middle

Explains the result-type rule and the val x: Double = 7 / 2 trap clearly.

for a senior

Discusses truncation toward zero vs floorDiv, explicit conversion philosophy, and Double-for-money pitfalls.

for a principal

Frames Kotlin's no-implicit-widening as a deliberate safety/design choice and weighs BigDecimal/Long-cents strategies for domain correctness.

## Integer vs floating-point division In Kotlin the `/` operator is overloaded per numeric type. When **both** operands are integer types (`Int`, `Long`, `Short`, `Byte`), `/` performs **integer division**: it divides and discards any fractional part, truncating **toward zero**. - `7 / 2` -> `3` (not 3.5) - `-7 / 2` -> `-3` (truncates toward zero, not toward negative infinity) - `1 / 2` -> `0` The **result type** follows the operands: `Int / Int` produces `Int`, `Long / Long` produces `Long`. ## Getting a fractional result Kotlin does **not** implicitly widen `Int` to `Double`. You must make at least one operand floating point so the `Double`/`Float` overload of `/` is chosen: ```kotlin 7 / 2 // 3 (Int division) 7.0 / 2 // 3.5 (Double division — literal 7.0 is Double) 7 / 2.0 // 3.5 7.toDouble() / 2 // 3.5 (explicit conversion) val bug: Double = 7 / 2 // 3.0 — division happens in Int FIRST, then 3 widens to 3.0 ``` That last line is the classic trap: the assignment target type does **not** change how the expression is evaluated; `7 / 2` is computed as `Int` arithmetic (`3`) and only then converted to `3.0`. ## Conversion functions Kotlin requires **explicit** conversions: `.toDouble()`, `.toFloat()`, `.toLong()`, `.toInt()`, etc. There is no automatic numeric promotion as in Java for assignment. ## Remainder The `%` operator returns the remainder: `7 % 2 == 1`, `-7 % 2 == -1` (sign follows the dividend). ## Money / exactness Because `Double` is binary floating point, `0.1 + 0.2 != 0.3`. For currency or exact decimals use `java.math.BigDecimal`.

  • Why does val x: Double = 7 / 2 give 3.0 and not 3.5?
    The right side is evaluated independently using Int division (7 / 2 = 3); the Double target type only triggers a widening of the already-computed 3 to 3.0.
  • How does Int division round — toward zero or toward negative infinity?
    Toward zero. So -7 / 2 is -3, not -4. (Math.floorDiv gives floored division if you need -4.)

Integer division is like sharing cookies among kids: 7 cookies, 2 kids, each gets 3 and you ignore the leftover crumb (that crumb is what % gives you).

saying these in an interview costs you the question

  • Believing 7 / 2 returns 3.5
  • Thinking the assignment type changes how the expression is computed
  • Assuming Kotlin auto-widens Int to Double like Java assignment
  • Saying Int division rounds, when it truncates
  • Using Double for money instead of BigDecimal

context

open as a page

In Kotlin, what do the comparison operators <, >, <=, >= actually translate to under the hood?

level: middleimportance: must knowfreq 65%

basics

~10 s

They all call a single method named compareTo. The compiler rewrites a < b into a.compareTo(b) < 0, and similarly for the others, comparing the returned number against zero.

open as a page

How do you perform bitwise operations in Kotlin given there are no &, |, ^, <<, >> symbols?

level: middleimportance: should knowfreq 45%

basics

~20 s

Kotlin uses named functions you write between the values, like a and b, a or b, a xor b, a shl 2, a shr 2. There are no &, |, ^, <<, or >> symbols like in Java.

open as a page

What happens on Int overflow in Kotlin arithmetic, and why doesn't `val total: Long = bigInt * bigInt` save you?

level: seniorimportance: should knowfreq 40%

basics

~20 s

Int math silently wraps around when it gets too big — no error. Assigning to a Long doesn't help, because the multiply already happened as Int and overflowed before the result became a Long. Make an operand a Long first.

open as a page

How would you make Kotlin's +, *, and < work on a custom Vector2 class, and what rules govern those operator functions?

level: seniorimportance: nice to knowfreq 30%

basics

~10 s

Write functions with special names marked with the operator keyword: plus for +, times for *, and compareTo for <. Kotlin then lets callers use the symbols directly on your type.

open as a page