From b45470279c03a8e286a0ed877e8e548ff05ea491 Mon Sep 17 00:00:00 2001 From: Colin Leach Date: Sat, 30 Aug 2025 14:39:04 -0700 Subject: [PATCH 01/12] Add Numbers concept --- concepts/numbers/.meta/config.json | 7 ++ concepts/numbers/about.md | 148 +++++++++++++++++++++++++++++ concepts/numbers/introduction.md | 140 +++++++++++++++++++++++++++ concepts/numbers/links.json | 14 +++ config.json | 5 + 5 files changed, 314 insertions(+) create mode 100644 concepts/numbers/.meta/config.json create mode 100644 concepts/numbers/about.md create mode 100644 concepts/numbers/introduction.md create mode 100644 concepts/numbers/links.json diff --git a/concepts/numbers/.meta/config.json b/concepts/numbers/.meta/config.json new file mode 100644 index 00000000..a6712f1a --- /dev/null +++ b/concepts/numbers/.meta/config.json @@ -0,0 +1,7 @@ +{ + "authors": [ + "colinleach" + ], + "contributors": [], + "blurb": "Kotlin has a variety of integer and floating point types, and a math library to manipulate them." +} diff --git a/concepts/numbers/about.md b/concepts/numbers/about.md new file mode 100644 index 00000000..85049d7e --- /dev/null +++ b/concepts/numbers/about.md @@ -0,0 +1,148 @@ +# About Numbers + +## Numerical types + +[Numbers][numbers] can be integer, unsigned integer, or floating point types. +Each comes in various "sizes", meaning how many bits it needs in memory. + +- Integers can be `Byte`, `Short`, `Int` or `Long`, respectively 8, 16, 32 and 64 bits. +- Unsigned integers have a `U` prefix: `UByte`, `UShort`, `UInt` or `ULong`. +- Floating point types are `Float` (32-bit) or `Double` (64-bit). + +Integer variables relying on type inference default to `Int`, even on 64-bit machines, but floating point variables default to `Double`. + +Other types can, of course, be specified, but there are a few syntactic shortcuts, and big integer literals become `Long` if they would overflow `Int`. + +```Kotlin +val one = 1 // defaults to Int +val threeBillion = 3_000_000_000 // Long, with optional underscores for clarity +val oneLong = 1L // Long +val oneByte: Byte = 1 +val oneDouble = 1.0 // defaults to Double +val oneFloat = 1.0f //Float +val lightSpeed = 3.0e8 // scientific notation (units of m/s) +``` + +Hexadecimal and binary literals are conventional: `0x7F` and `0b100101` respectively. +Octal literals are not supported in Kotlin. + +## Arithmetic + +The basic arithmetic operators are the same as in many languages: + +```Kotlin +4 + 3 // => 7 +4 - 3 // => 1 +4 * 3 // => 12 +4 / 3 // => 1 Int / Int always gives an Int +-8 / 3 // => -2 Truncated towards zero +-8.0 / 3 // => -2.6666666666666665 +``` + +To get a floating point result from division, at least one of the numerator / denominator must be floating point. + +Division by zero is more interesting. + +```Kotlin +1 / 0 // => java.lang.ArithmeticException: / by zero +3.0 / 0.0 // => Infinity +0.0 / 0.0 // => NaN (Not a Number) +``` + +Integer division by zero is an error, but [IEEE floating point standards][IEEE] can apply in other cases. + +The modulo operator `%` gives the remainder from integer division: + +```Kotlin +8 % 3 // => 2 +``` + +Kotlin, like other JVM languages, has no exponentiation operator (_this annoys scientists and engineers_). +We need to use the [`pow()`][pow] function from the [`math`][math] library, and the number being raised to some power must be `Float` or `Double`. + +```kotlin +2.0.pow(3) // => 8.0 +2.pow(3) // Unresolved reference (2 is Int, so not allowed) +``` + +## Rounding + +The [`math`][math] library contains several functions to round floating point numbers to a nearby integer. + +_Did the last line sound slightly odd?_ +When we say "a nearby integer", there are two questions: + +- Is the return value still Float/Double, or is it converted to Int/Long? +- How are ties rounded? Does `4.5` round to `4` or `5`? + +It is not Kotlin's fault if this seems complicated. +Mathematicians have been arguing about this for centuries. + +### `round()`, `floor()`, `ceil()`, `truncate()` + +These four functions all return the same floating-point type as the input, but differ in how they round. + +- [`round()`][round] gives the _nearest_ integer if this is unambiguous, or the _nearest even_ integer when tied. +- [`floor()`][floor] rounds towards negative infinity. +- [`ceil()`][ceil] rounds towards positive infinity +- [`truncate()`][truncate] rounds towards zero + +```kotlin +round(4.7) // => 5.0 (nearest integer) +round(4.5) // => 4.0 (nearest even integer) + +floor(4.7) // => 4.0 (towards -Inf) +floor(-4.7) // => 5.0 + +ceil(4.7) // => 5.0 (towards +Inf) +ceil(-4.7) // => -4.0 + +truncate(4.7) // => 4.0 (towards zero) +truncate(-4.7) // => -4.0 +``` + +### `roundToInt()`, `roundToLong()` + +These two functions do a type conversion after rounding, so the return type is `Int` or `Long` respectively. + +Ties are always rounded towards positive infinity. + +```kotlin +4.3.roundToInt() // => 4 (nearest integer) +4.5.roundToInt() // => 5 (nearest integer towards +Inf) +(-4.5).roundToInt() // => -4 +``` + +Note also the different syntax: `x.roundToInt()` versus `round(x)`. + +## Type conversions + +Kotlin will quietly do implicit conversions in a few cases, for example `Int` to `Double` in a mixed arithmetic expression: + +```Kotlin +3 + 4.0 // => 7.0 +``` + +Internally, the `+` operator is overloaded to handle this. + +More generally, explicit conversions are required: + +```Kotlin +val x = 7.3 +x.toInt() // => 7 + +val n = 42 +n.toDouble() // => 42.0 +``` + +See the [manual][conversions] for the full list of `toX()` methods. + +[numbers]: https://kotlinlang.org/docs/numbers.html +[IEEE]: https://en.wikipedia.org/wiki/IEEE_754 +[conversions]: https://kotlinlang.org/docs/numbers.html#explicit-number-conversions +[pow]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.math/pow.html +[math]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.math/ +[round]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.math/round.html +[floor]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.math/floor.html +[ceil]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.math/ceil.html +[truncate]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.math/truncate.html diff --git a/concepts/numbers/introduction.md b/concepts/numbers/introduction.md new file mode 100644 index 00000000..09c4c108 --- /dev/null +++ b/concepts/numbers/introduction.md @@ -0,0 +1,140 @@ +# Introduction + +## Numerical types + +[Numbers][numbers] can be integer, unsigned integer, or floating point types. +Each comes in various "sizes", meaning how many bits it needs in memory. + +- Integers can be `Byte`, `Short`, `Int` or `Long`, respectively 8, 16, 32 and 64 bits. +- Unsigned integers have a `U` prefix: `UByte`, `UShort`, `UInt` or `ULong`. +- Floating point types are `Float` (32-bit) or `Double` (64-bit). + +Integer variables relying on type inference default to `Int`, even on 64-bit machines, but floating point variables default to `Double`. + +Other types can, of course, be specified, but there are a few syntactic shortcuts, and big integer literals become `Long` if they would overflow `Int`. + +```Kotlin +val one = 1 // defaults to Int +val threeBillion = 3_000_000_000 // Long, with optional underscores for clarity +val oneLong = 1L // Long +val oneByte: Byte = 1 +val oneDouble = 1.0 // defaults to Double +val oneFloat = 1.0f //Float +val lightSpeed = 3.0e8 // scientific notation (units of m/s) +``` + +Hexadecimal and binary literals are conventional: `0x7F` and `0b100101` respectively. +Octal literals are not supported in Kotlin. + +## Arithmetic + +The basic arithmetic operators are the same as in many languages: + +```Kotlin +4 + 3 // => 7 +4 - 3 // => 1 +4 * 3 // => 12 +4 / 3 // => 1 Int / Int always gives an Int +-8 / 3 // => -2 Truncated towards zero +-8.0 / 3 // => -2.6666666666666665 +``` + +To get a floating point result from division, at least one of the numerator / denominator must be floating point. + +Division by zero is more interesting. + +```Kotlin +1 / 0 // => java.lang.ArithmeticException: / by zero +3.0 / 0.0 // => Infinity +0.0 / 0.0 // => NaN (Not a Number) +``` + +Integer division by zero is an error, but IEEE floating point standards can apply in other cases. + +The modulo operator `%` gives the remainder from integer division: + +```Kotlin +8 % 3 // => 2 +``` + +Kotlin, like other JVM languages, has no exponentiation operator. +We need to use the `pow()` function from the [`math`][math] library, and the number being raised to some power must be `Float` or `Double`. + +```kotlin +2.0.pow(3) // => 8.0 +2.pow(3) // Unresolved reference (2 is Int, so not allowed) +``` + +## Rounding + +The [`math`][math] library contains several functions to round floating point numbers to a nearby integer. + +_Did the last line sound slightly odd?_ +When we say "a nearby integer", there are two questions: + +- Is the return value still Float/Double, or is it converted to Int/Long? +- How are ties rounded? Does `4.5` round to `4` or `5`? + +It is not Kotlin's fault if this seems complicated. +Mathematicians have been arguing about this for centuries. + +### `round()`, `floor()`, `ceil()`, `truncate()` + +These four functions all return the same floating-point type as the input, but differ in how they round. + +- `round()` gives the _nearest_ integer if this is unambiguous, or the _nearest even_ integer when tied. +- `floor()` rounds towards negative infinity. +- `ceil()` rounds towards positive infinity +- `truncate()` rounds towards zero + +```kotlin +round(4.7) // => 5.0 (nearest integer) +round(4.5) // => 4.0 (nearest even integer) + +floor(4.7) // => 4.0 (towards -Inf) +floor(-4.7) // => 5.0 + +ceil(4.7) // => 5.0 (towards +Inf) +ceil(-4.7) // => -4.0 + +truncate(4.7) // => 4.0 (towards zero) +truncate(-4.7) // => -4.0 +``` + +### `roundToInt()`, `roundToLong()` + +These two functions do a type conversion after rounding, so the return type is `Int` or `Long` respectively. + +Ties are always rounded towards positive infinity. + +```kotlin +4.3.roundToInt() // => 4 (nearest integer) +4.5.roundToInt() // => 5 (nearest integer towards +Inf) +(-4.5).roundToInt() // => -4 +``` + +Note also the different syntax: `x.roundToInt()` versus `round(x)`. + +## Type conversions + +Kotlin will quietly do implicit conversions in a few cases, for example `Int` to `Double` in a mixed arithmetic expression: + +```Kotlin +3 + 4.0 // => 7.0 +``` + +More generally, explicit conversions are required: + +```Kotlin +val x = 7.3 +x.toInt() // => 7 + +val n = 42 +n.toDouble() // => 42.0 +``` + +See the [manual][conversions] for the full list of `toX()` methods. + +[numbers]: https://kotlinlang.org/docs/numbers.html +[conversions]: https://kotlinlang.org/docs/numbers.html#explicit-number-conversions +[math]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.math/ diff --git a/concepts/numbers/links.json b/concepts/numbers/links.json new file mode 100644 index 00000000..3a725bc6 --- /dev/null +++ b/concepts/numbers/links.json @@ -0,0 +1,14 @@ +[ + { + "url": "https://kotlinlang.org/docs/numbers.html", + "description": "Kotlin introduction to numbers" + }, + { + "url": "https://kotlinlang.org/docs/numbers.html#explicit-number-conversions", + "description": "Numeric type conversions" + }, + { + "url": "https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.math/", + "description": "Kotlin math library" + } +] diff --git a/config.json b/config.json index ba7a0c1d..b0fb110e 100644 --- a/config.json +++ b/config.json @@ -1387,6 +1387,11 @@ "uuid": "168827c0-4867-449a-ad22-611c87314c48", "slug": "conditionals", "name": "Conditionals" + }, + { + "uuid": "0501f1e3-8443-4386-9107-4c28cb10469f", + "slug": "numbers", + "name": "Numbers" } ], "key_features": [ From 8675412b00052822ad1b89818a8e625d3256454a Mon Sep 17 00:00:00 2001 From: Colin Leach Date: Sat, 30 Aug 2025 21:21:40 -0700 Subject: [PATCH 02/12] Enhance numbers documentation with type limits and links Response to reviewer comments --- concepts/numbers/about.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/concepts/numbers/about.md b/concepts/numbers/about.md index 85049d7e..1dfba007 100644 --- a/concepts/numbers/about.md +++ b/concepts/numbers/about.md @@ -5,7 +5,10 @@ [Numbers][numbers] can be integer, unsigned integer, or floating point types. Each comes in various "sizes", meaning how many bits it needs in memory. -- Integers can be `Byte`, `Short`, `Int` or `Long`, respectively 8, 16, 32 and 64 bits. +Unlike some scripting languages (Ruby, recent versions of Python), each type in Kotlin has a maximum and minimum value it can store. +Assigning larger values will cause ["overflow"][wiki-overflow], causing either an exception (_bad_) or corrupted data (_worse_). + +- Integers can be `Byte`, `Short`, `Int` or `Long`, respectively 8, 16, 32 and 64 bits (1, 2 4, 8 bytes). - Unsigned integers have a `U` prefix: `UByte`, `UShort`, `UInt` or `ULong`. - Floating point types are `Float` (32-bit) or `Double` (64-bit). @@ -19,7 +22,7 @@ val threeBillion = 3_000_000_000 // Long, with optional underscores for clarity val oneLong = 1L // Long val oneByte: Byte = 1 val oneDouble = 1.0 // defaults to Double -val oneFloat = 1.0f //Float +val oneFloat = 1.0f // Float val lightSpeed = 3.0e8 // scientific notation (units of m/s) ``` @@ -49,7 +52,7 @@ Division by zero is more interesting. 0.0 / 0.0 // => NaN (Not a Number) ``` -Integer division by zero is an error, but [IEEE floating point standards][IEEE] can apply in other cases. +Integer division by zero is an error, but [IEEE floating point standards][wiki-IEEE] can apply in other cases. The modulo operator `%` gives the remainder from integer division: @@ -138,7 +141,7 @@ n.toDouble() // => 42.0 See the [manual][conversions] for the full list of `toX()` methods. [numbers]: https://kotlinlang.org/docs/numbers.html -[IEEE]: https://en.wikipedia.org/wiki/IEEE_754 +[wiki-IEEE]: https://en.wikipedia.org/wiki/IEEE_754 [conversions]: https://kotlinlang.org/docs/numbers.html#explicit-number-conversions [pow]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.math/pow.html [math]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.math/ @@ -146,3 +149,4 @@ See the [manual][conversions] for the full list of `toX()` methods. [floor]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.math/floor.html [ceil]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.math/ceil.html [truncate]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.math/truncate.html +[wiki-overflow]: https://en.wikipedia.org/wiki/Integer_overflow From a80986cdcb1b36b82e674818492acb4a2334bc74 Mon Sep 17 00:00:00 2001 From: Colin Leach Date: Sat, 30 Aug 2025 21:42:33 -0700 Subject: [PATCH 03/12] Update about.md with MAX_VALUE and MIN_VALUE links Clarified maximum and minimum value references for Kotlin types. --- concepts/numbers/about.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/concepts/numbers/about.md b/concepts/numbers/about.md index 1dfba007..b619324d 100644 --- a/concepts/numbers/about.md +++ b/concepts/numbers/about.md @@ -5,7 +5,7 @@ [Numbers][numbers] can be integer, unsigned integer, or floating point types. Each comes in various "sizes", meaning how many bits it needs in memory. -Unlike some scripting languages (Ruby, recent versions of Python), each type in Kotlin has a maximum and minimum value it can store. +Unlike some scripting languages (Ruby, recent versions of Python), each type in Kotlin has a maximum ([`MAX_VALUE][max_value] and minimum ([`MIN_VALUE`][min_value]) value it can store. Assigning larger values will cause ["overflow"][wiki-overflow], causing either an exception (_bad_) or corrupted data (_worse_). - Integers can be `Byte`, `Short`, `Int` or `Long`, respectively 8, 16, 32 and 64 bits (1, 2 4, 8 bytes). @@ -150,3 +150,5 @@ See the [manual][conversions] for the full list of `toX()` methods. [ceil]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.math/ceil.html [truncate]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.math/truncate.html [wiki-overflow]: https://en.wikipedia.org/wiki/Integer_overflow +[max_value]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/-companion/#-244053257%2FProperties%2F-956074838 +[min_value]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/-companion/#-1907397559%2FProperties%2F-956074838 From 7a1d11af19145391a64ff446a46e59418cc3e56a Mon Sep 17 00:00:00 2001 From: Colin Leach Date: Sat, 30 Aug 2025 21:43:54 -0700 Subject: [PATCH 04/12] Fix formatting issues in numbers about documentation --- concepts/numbers/about.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/concepts/numbers/about.md b/concepts/numbers/about.md index b619324d..a7246045 100644 --- a/concepts/numbers/about.md +++ b/concepts/numbers/about.md @@ -5,7 +5,7 @@ [Numbers][numbers] can be integer, unsigned integer, or floating point types. Each comes in various "sizes", meaning how many bits it needs in memory. -Unlike some scripting languages (Ruby, recent versions of Python), each type in Kotlin has a maximum ([`MAX_VALUE][max_value] and minimum ([`MIN_VALUE`][min_value]) value it can store. +Unlike some scripting languages (Ruby, recent versions of Python), each type in Kotlin has a maximum ([`MAX_VALUE`][max_value] and minimum ([`MIN_VALUE`][min_value]) value it can store. Assigning larger values will cause ["overflow"][wiki-overflow], causing either an exception (_bad_) or corrupted data (_worse_). - Integers can be `Byte`, `Short`, `Int` or `Long`, respectively 8, 16, 32 and 64 bits (1, 2 4, 8 bytes). From 083d2e153e7b9341a3e294d5e28082a4b7c7f1ad Mon Sep 17 00:00:00 2001 From: Colin Leach Date: Sat, 30 Aug 2025 21:44:31 -0700 Subject: [PATCH 05/12] Fix formatting in about.md for Kotlin number types --- concepts/numbers/about.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/concepts/numbers/about.md b/concepts/numbers/about.md index a7246045..937e9b1c 100644 --- a/concepts/numbers/about.md +++ b/concepts/numbers/about.md @@ -5,7 +5,7 @@ [Numbers][numbers] can be integer, unsigned integer, or floating point types. Each comes in various "sizes", meaning how many bits it needs in memory. -Unlike some scripting languages (Ruby, recent versions of Python), each type in Kotlin has a maximum ([`MAX_VALUE`][max_value] and minimum ([`MIN_VALUE`][min_value]) value it can store. +Unlike some scripting languages (Ruby, recent versions of Python), each type in Kotlin has a maximum ([`MAX_VALUE`][max_value]) and minimum ([`MIN_VALUE`][min_value]) value it can store. Assigning larger values will cause ["overflow"][wiki-overflow], causing either an exception (_bad_) or corrupted data (_worse_). - Integers can be `Byte`, `Short`, `Int` or `Long`, respectively 8, 16, 32 and 64 bits (1, 2 4, 8 bytes). From 7e28729a1d4cf4ea004d8267d858e1fa56ce1620 Mon Sep 17 00:00:00 2001 From: Colin Leach Date: Sun, 31 Aug 2025 08:32:35 -0700 Subject: [PATCH 06/12] revised overflow section and reference format --- concepts/numbers/about.md | 47 ++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/concepts/numbers/about.md b/concepts/numbers/about.md index 937e9b1c..f893f36c 100644 --- a/concepts/numbers/about.md +++ b/concepts/numbers/about.md @@ -2,11 +2,16 @@ ## Numerical types -[Numbers][numbers] can be integer, unsigned integer, or floating point types. +[Numbers][ref-numbers] can be integer, unsigned integer, or floating point types. Each comes in various "sizes", meaning how many bits it needs in memory. -Unlike some scripting languages (Ruby, recent versions of Python), each type in Kotlin has a maximum ([`MAX_VALUE`][max_value]) and minimum ([`MIN_VALUE`][min_value]) value it can store. -Assigning larger values will cause ["overflow"][wiki-overflow], causing either an exception (_bad_) or corrupted data (_worse_). +Unlike some scripting languages (Ruby, recent versions of Python), each numeric type in Kotlin has a maximum ([`MAX_VALUE`][ref-max_value]) and minimum ([`MIN_VALUE`][ref-min_value]) value it can store. +Assigning larger values will cause ["overflow"][wiki-overflow], resulting in either an exception (_bad_) or corrupted data (_worse_). + +```kotlin +Int.MAX_VALUE // => 2147483647 (maximum for a 32-bit signed integer) +Int.MAX_VALUE + 1 // -2147483648 (overflow gives a negative result!) +``` - Integers can be `Byte`, `Short`, `Int` or `Long`, respectively 8, 16, 32 and 64 bits (1, 2 4, 8 bytes). - Unsigned integers have a `U` prefix: `UByte`, `UShort`, `UInt` or `ULong`. @@ -61,7 +66,7 @@ The modulo operator `%` gives the remainder from integer division: ``` Kotlin, like other JVM languages, has no exponentiation operator (_this annoys scientists and engineers_). -We need to use the [`pow()`][pow] function from the [`math`][math] library, and the number being raised to some power must be `Float` or `Double`. +We need to use the [`pow()`][ref-pow] function from the [`math`][ref-math] library, and the number being raised to some power must be `Float` or `Double`. ```kotlin 2.0.pow(3) // => 8.0 @@ -70,7 +75,7 @@ We need to use the [`pow()`][pow] function from the [`math`][math] library, and ## Rounding -The [`math`][math] library contains several functions to round floating point numbers to a nearby integer. +The [`math`][ref-math] library contains several functions to round floating point numbers to a nearby integer. _Did the last line sound slightly odd?_ When we say "a nearby integer", there are two questions: @@ -79,16 +84,16 @@ When we say "a nearby integer", there are two questions: - How are ties rounded? Does `4.5` round to `4` or `5`? It is not Kotlin's fault if this seems complicated. -Mathematicians have been arguing about this for centuries. +Mathematicians have been arguing about it for centuries. ### `round()`, `floor()`, `ceil()`, `truncate()` These four functions all return the same floating-point type as the input, but differ in how they round. -- [`round()`][round] gives the _nearest_ integer if this is unambiguous, or the _nearest even_ integer when tied. -- [`floor()`][floor] rounds towards negative infinity. -- [`ceil()`][ceil] rounds towards positive infinity -- [`truncate()`][truncate] rounds towards zero +- [`round()`][ref-round] gives the _nearest_ integer if this is unambiguous, or the _nearest even_ integer when tied. +- [`floor()`][ref-floor] rounds towards negative infinity. +- [`ceil()`][ref-ceil] rounds towards positive infinity +- [`truncate()`][ref-truncate] rounds towards zero ```kotlin round(4.7) // => 5.0 (nearest integer) @@ -138,17 +143,17 @@ val n = 42 n.toDouble() // => 42.0 ``` -See the [manual][conversions] for the full list of `toX()` methods. +See the [manual][ref-conversions] for the full list of `toX()` methods. -[numbers]: https://kotlinlang.org/docs/numbers.html +[ref-numbers]: https://kotlinlang.org/docs/numbers.html [wiki-IEEE]: https://en.wikipedia.org/wiki/IEEE_754 -[conversions]: https://kotlinlang.org/docs/numbers.html#explicit-number-conversions -[pow]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.math/pow.html -[math]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.math/ -[round]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.math/round.html -[floor]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.math/floor.html -[ceil]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.math/ceil.html -[truncate]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.math/truncate.html +[ref-conversions]: https://kotlinlang.org/docs/numbers.html#explicit-number-conversions +[ref-pow]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.math/pow.html +[ref-math]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.math/ +[ref-round]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.math/round.html +[ref-floor]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.math/floor.html +[ref-ceil]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.math/ceil.html +[ref-truncate]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.math/truncate.html [wiki-overflow]: https://en.wikipedia.org/wiki/Integer_overflow -[max_value]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/-companion/#-244053257%2FProperties%2F-956074838 -[min_value]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/-companion/#-1907397559%2FProperties%2F-956074838 +[ref-max_value]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/-companion/#-244053257%2FProperties%2F-956074838 +[ref-min_value]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/-companion/#-1907397559%2FProperties%2F-956074838 From 4fc6266086fad50a7d97db03359cc8140f341878 Mon Sep 17 00:00:00 2001 From: Colin Leach Date: Sun, 31 Aug 2025 16:07:40 -0700 Subject: [PATCH 07/12] Fix formatting in config.json blurb typo (spotted by @BNAndras) --- concepts/numbers/.meta/config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/concepts/numbers/.meta/config.json b/concepts/numbers/.meta/config.json index a6712f1a..60779647 100644 --- a/concepts/numbers/.meta/config.json +++ b/concepts/numbers/.meta/config.json @@ -3,5 +3,5 @@ "colinleach" ], "contributors": [], - "blurb": "Kotlin has a variety of integer and floating point types, and a math library to manipulate them." + "blurb": "Kotlin has a variety of integer and floating point types, and a math library to manipulate them." } From 80aef38a4ba5f688e0106aba13bf023ea6a958ea Mon Sep 17 00:00:00 2001 From: Colin Leach Date: Sun, 31 Aug 2025 16:14:42 -0700 Subject: [PATCH 08/12] Update integer type descriptions in about.md Response to comments in #713 (@BNAndras) --- concepts/numbers/about.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/concepts/numbers/about.md b/concepts/numbers/about.md index f893f36c..e2bcabf8 100644 --- a/concepts/numbers/about.md +++ b/concepts/numbers/about.md @@ -13,8 +13,8 @@ Int.MAX_VALUE // => 2147483647 (maximum for a 32-bit signed integer) Int.MAX_VALUE + 1 // -2147483648 (overflow gives a negative result!) ``` -- Integers can be `Byte`, `Short`, `Int` or `Long`, respectively 8, 16, 32 and 64 bits (1, 2 4, 8 bytes). -- Unsigned integers have a `U` prefix: `UByte`, `UShort`, `UInt` or `ULong`. +- Integers can be `Byte`, `Short`, `Int` or `Long`, respectively 8, 16, 32 and 64 bits (1, 2 4, 8 bytes), and can be positive or negative. +- Unsigned integers have a `U` prefix: `UByte`, `UShort`, `UInt` or `ULong`, and can only represent numbers ≥ 0. - Floating point types are `Float` (32-bit) or `Double` (64-bit). Integer variables relying on type inference default to `Int`, even on 64-bit machines, but floating point variables default to `Double`. @@ -31,7 +31,7 @@ val oneFloat = 1.0f // Float val lightSpeed = 3.0e8 // scientific notation (units of m/s) ``` -Hexadecimal and binary literals are conventional: `0x7F` and `0b100101` respectively. +Hexadecimal and binary literals are the same as in many languages: `0x7F` and `0b100101` respectively. Octal literals are not supported in Kotlin. ## Arithmetic From bd7e92591b44ede085a8a41200703da29bfac8c2 Mon Sep 17 00:00:00 2001 From: Colin Leach Date: Mon, 1 Sep 2025 11:09:55 -0700 Subject: [PATCH 09/12] clarified integer division --- concepts/numbers/about.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/concepts/numbers/about.md b/concepts/numbers/about.md index e2bcabf8..eb4bfe73 100644 --- a/concepts/numbers/about.md +++ b/concepts/numbers/about.md @@ -47,7 +47,8 @@ The basic arithmetic operators are the same as in many languages: -8.0 / 3 // => -2.6666666666666665 ``` -To get a floating point result from division, at least one of the numerator / denominator must be floating point. +To get a floating point result, at least one of the numbers in the calculation must be floating point. +This is particularly significant for division, as integer division often leads to truncation. Division by zero is more interesting. From 7661ce96698fbf0afbdb89d9dd5b37866b17a87a Mon Sep 17 00:00:00 2001 From: Colin Leach Date: Tue, 2 Sep 2025 08:55:00 -0700 Subject: [PATCH 10/12] Update concepts/numbers/about.md Co-authored-by: Derk-Jan Karrenbeld --- concepts/numbers/about.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/concepts/numbers/about.md b/concepts/numbers/about.md index eb4bfe73..568146c0 100644 --- a/concepts/numbers/about.md +++ b/concepts/numbers/about.md @@ -31,7 +31,7 @@ val oneFloat = 1.0f // Float val lightSpeed = 3.0e8 // scientific notation (units of m/s) ``` -Hexadecimal and binary literals are the same as in many languages: `0x7F` and `0b100101` respectively. +Hexadecimal literals start with `0x`, e.g. `0x7F`, and binary literals start with `0b`, e.g. `0b100101`. Octal literals are not supported in Kotlin. ## Arithmetic From 5e22f518b94b7a0e12a66cce9ef0432fa1d09c39 Mon Sep 17 00:00:00 2001 From: Colin Leach Date: Tue, 2 Sep 2025 09:50:51 -0700 Subject: [PATCH 11/12] Update concepts/numbers/about.md Co-authored-by: Derk-Jan Karrenbeld --- concepts/numbers/about.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/concepts/numbers/about.md b/concepts/numbers/about.md index 568146c0..206b2e23 100644 --- a/concepts/numbers/about.md +++ b/concepts/numbers/about.md @@ -53,11 +53,13 @@ This is particularly significant for division, as integer division often leads t Division by zero is more interesting. ```Kotlin -1 / 0 // => java.lang.ArithmeticException: / by zero +1 / 0 // => java.lang.ArithmeticException: / by zero 3.0 / 0.0 // => Infinity 0.0 / 0.0 // => NaN (Not a Number) ``` +That's because floating point operations follow the [IEEE-standard for Floating Point math](https://en.wikipedia.org/wiki/IEEE_754). + Integer division by zero is an error, but [IEEE floating point standards][wiki-IEEE] can apply in other cases. The modulo operator `%` gives the remainder from integer division: From 8a4d7592586cbe67e76f04509bddd5eec8be4ae7 Mon Sep 17 00:00:00 2001 From: Colin Leach Date: Tue, 2 Sep 2025 09:51:34 -0700 Subject: [PATCH 12/12] Update concepts/numbers/about.md Co-authored-by: Kah Goh --- concepts/numbers/about.md | 41 +++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/concepts/numbers/about.md b/concepts/numbers/about.md index 206b2e23..277f411f 100644 --- a/concepts/numbers/about.md +++ b/concepts/numbers/about.md @@ -36,19 +36,40 @@ Octal literals are not supported in Kotlin. ## Arithmetic -The basic arithmetic operators are the same as in many languages: +The basic arithmetic operators are the same as in many languages. +When the numbers in the calculation are the same type, the result will also be the same type: -```Kotlin -4 + 3 // => 7 -4 - 3 // => 1 -4 * 3 // => 12 -4 / 3 // => 1 Int / Int always gives an Int --8 / 3 // => -2 Truncated towards zero --8.0 / 3 // => -2.6666666666666665 +```kotlin +4 + 3 // => 7 Int + Int = Int +4 - 3 // => 1 Int - Int = Int +4L * 3L // => 12 Long * Long = Long +6.0 / 2.0 // => 3.0 Double / Double = Double +``` + +If the numbers are different types, Kotlin will infer the result's type to mitigate data loss: + +```kotlin +4 + 3.0 // => 7.0 Int + Double = Double +10.5 - 3.125f // => 7.375 Double - Float = Double +7L * 1.125 // => 7.875 Long * Double = Double +10L / 3.0 // => 3.3333333333333335 Long / Double = Double +``` + +This is particularly significant for division, as dividing an integer (for example an Int) by another integer (for example an Int) will give an integer (in this case an Int): + +```kotlin +4 / 3 // => 1 Int / Int always gives an Int +-8 / 3 // => -2 Truncated towards zero +``` + +To keep the decimal part, convert one of the numbers to a Float or Double: + +```kotlin +-8.0 / 3 // => -2.6666666666666665 +-8 / 3.0 // => -2.6666666666666665 +-8.0 / 3.0 // => -2.6666666666666665 ``` -To get a floating point result, at least one of the numbers in the calculation must be floating point. -This is particularly significant for division, as integer division often leads to truncation. Division by zero is more interesting.