Different types of numbers are stored in different ways.

If you define an identifier and assign an integer value to it, Kotlin infers the `Int`

type:

```
// NumberTypes/InferInt.kt
fun main(args: Array<String>) {
val million = 1_000_000 // Infers Int
println(million)
}
/* Output:
1000000
*/
```

Kotlin allows underscores in numerical values, to make numbers more readable.

The basic mathematical operators for numbers are the same as the ones available in most programming languages: addition (`+`

), subtraction (`-`

), division (`/`

), multiplication (`*`

) and modulus (`%`

, which produces the remainder from integer division):

```
// NumberTypes/Modulus.kt
fun main(args: Array<String>) {
val numerator: Int = 19
val denominator: Int = 10
println(numerator % denominator)
}
/* Output:
9
*/
```

Integer division truncates, rather than rounds, the result:

```
// NumberTypes/IntDivisionTruncates.kt
fun main(args: Array<String>) {
val numerator: Int = 19
val denominator: Int = 10
println(numerator / denominator)
}
/* Output:
1
*/
```

If the operation had rounded the result, the output would be `2`

.

Programming languages define the order in which operations are performed. The order of arithmetic operations is straightforward:

The multiplication operation `5 * 6`

is performed first, followed by the addition `45 + 30`

.

If you want `45 + 5`

to happen first, use parentheses:

```
// NumberTypes/OpOrderParens.kt
fun main(args: Array<String>) {
println( (45 + 5) * 6 )
}
/* Output:
300
*/
```

As another example, let’s calculate *body mass index* (BMI), which is weight in kilograms divided by height in meters squared. If you have a BMI of less than `18.5`

, you are underweight. Between `18.5`

and `24.9`

is normal weight. BMI of `25`

and higher is overweight. Here, we see the preferred formatting style when you can’t fit all function arguments on a single line:

```
// NumberTypes/BMI.kt
fun getBmiStatus(
kg: Double,
heightM: Double
): String {
val bmi = kg / (heightM * heightM) // [1]
return if (bmi < 18.5) "Underweight"
else if (bmi < 25) "Normal weight"
else "Overweight"
}
fun main(args: Array<String>) {
val kg = 72.57 // 160 lbs
val heightM = 1.727 // 68 inches
val status = getBmiStatus(kg, heightM)
println(status)
}
/* Output:
Normal weight
*/
```

**[1]**If you remove the parentheses, you divide`kg`

by`heightM`

then multiply that result by`heightM`

. That’s a much larger number, and the wrong answer.

`BMI.kt`

uses `Double`

s for the weight and height. A `Double`

holds very large and very small floating-point numbers. Here’s a version using `Int`

s (for English units instead of metric):

```
// NumberTypes/IntegerMath.kt
fun getBmiStatusInt(
lbs: Int,
height: Int
): String {
val bmi =
lbs / (height * height) * 703.07 // [1]
return if (bmi < 18.5) "Underweight"
else if (bmi < 25) "Normal weight"
else "Overweight"
}
fun main(args: Array<String>) {
val lbs = 160
val height = 68
val status = getBmiStatusInt(lbs, height)
println(status)
}
/* Output:
Underweight
*/
```

Why does the result differ from the previous version that uses `Double`

s? When you divide an integer by another integer, Kotlin produces an integer result. The standard way to deal with the remainder during integer division is *truncation*, meaning “chop it off and throw it away” (there’s no rounding). So if you divide `5`

by `2`

you get `2`

, and `7/10`

is zero. When Kotlin calculates `bmi`

in expression **[1]**, it divides `160`

by `68 * 68`

and gets zero. It then multiplies zero by `703.07`

to get zero.

To avoid this problem, first multiply by `703.07`

to force the result type of the computation to be `Double`

:

Note how using `Double`

arguments in `BMI.kt`

’s version of `getBmiStatus()`

prevents this problem. Try to convert computations to the desired type as early as possible, otherwise you might lose accuracy.

All programming languages have limits to what they can store within an integer. Kotlin’s `Int`

type is restricted to the values between `-2`

^{31} and `+2`

^{31}`-1`

. (That constraint comes from the 32-bit representation for `Int`

values). If you sum or multiply two `Int`

s that are big enough, you’ll overflow the result:

```
// NumberTypes/IntegerOverflow.kt
fun main(args: Array<String>) {
val i: Int = Int.MAX_VALUE
println(i + i)
}
/* Output:
-2
*/
```

`Int.MAX_VALUE`

is the special predefined value which is the largest number an `Int`

can hold.

Not only do you get an output that is clearly not large—this is the effect of the overflow—but you also get a warning during compilation.

To achieve better performance for numerical operations, Kotlin doesn’t prevent integer overflow, and it can’t always detect overflow during compilation. Preventing overflow is your responsibility as a developer.

If your program contains large numbers, you can use `Long`

s, which accommodate values from `-2`

^{63} to `+2`

^{63}`-1`

. To define a `val`

of type `Long`

, you can specify the type explicitly or put `L`

at the end of a numeric literal, which tells the compiler to treat that value as a `Long`

:

```
// NumberTypes/LongConstants.kt
fun main(args: Array<String>) {
val i = 0 // Infers Int
val l1 = 0L // L creates Long
val l2: Long = 0 // Explicit type
println("$l1 $l2")
}
/* Output:
0 0
*/
```

By changing to `Long`

s we prevent the overflow in `IntegerOverflow.kt`

because `Long`

s hold much larger values:

```
// NumberTypes/UsingLongs.kt
fun main(args: Array<String>) {
val i = Int.MAX_VALUE
println(0L + i + i) // [1]
println(1_000_000 * 1_000_000L) // [2]
}
/* Output:
4294967294
1000000000000
*/
```

Using a numeric literal in both **[1]** and **[2]** forces `Long`

calculations, and also produces a result of type `Long`

. The location where the `L`

appears is unimportant. If one of the values is `Long`

, the resulting expression is `Long`

.

Although they can hold much larger values than `Int`

s, `Long`

s still have size limitations:

```
// NumberTypes/BiggestLong.kt
fun main(args: Array<String>) {
println(Long.MAX_VALUE)
}
/* Output:
9223372036854775807
*/
```

`Long.MAX_VALUE`

is the special predefined value which is the largest number a `Long`

can hold. Previous Next

©2018 Mindview LLC. All Rights Reserved.