-
-
Notifications
You must be signed in to change notification settings - Fork 204
Add Numbers concept #711
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Add Numbers concept #711
Changes from 1 commit
b454702
8675412
a80986c
7a1d11a
083d2e1
7e28729
4fc6266
80aef38
bd7e925
7661ce9
5e22f51
8a4d759
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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." | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -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 | ||||||||||||||||||||||||||
colinleach marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||||||||||||||
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. | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
It just doesn't exist for multiplatform, but does exist for JVM... |
||||||||||||||||||||||||||
## 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 | ||||||||||||||||||||||||||
|
4 / 3 // => 1 Int / Int always gives an Int | |
-8 / 3 // => -2 Truncated towards zero | |
-8.0 / 3 // => -2.6666666666666665 | |
12 / 4 => 3 | |
``` | |
When dividing an integer (for example an Int) by another integer (for example an Int), the result will also be an integer (in this case an Int): | |
```kotlin | |
4 / 3 // => 1 Int / Int always gives an Int | |
-8 / 3 // => -2 Truncated towards zero | |
``` |
colinleach marked this conversation as resolved.
Show resolved
Hide resolved
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. | ||
colinleach marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't this true for any arithmetic operator in Kotlin? For example There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. True. However, only integer division causes large rounding errors. I'll try to make the wording clearer. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Is this better? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was wondering if it's worth explaining that Kotlin works out the result number types in the calculations. I'll try suggest something in a separate comment. |
||
|
||
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 | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @colinleach I wasn't quite sure if you meant to remove bits from this introduction as well or just from the exercise's introduction in the comment (ignore this if you meant just from the exercise introduction), but if you're looking for something to cut or separate out, the Cars Assemble exercise dosen't cover rounding and the use of the math library. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you make a cut-down version in the exercise, I'll wait till that is merged then copy it back to the concept. Probably easier than trying to keep them in sync as yours goes through review and editing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure what to do about the math library. I covered rounding here because some other tracks do (with an exercise that needs it such as I think I'll leave it in the About for now. If any of the later exercises need rounding, we can move this section to there. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Leave it in about, we can remove from introduction as we build the track out. Moving content between concepts is far easier than adding new content! |
||
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/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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" | ||
} | ||
] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It makes sense to quickly explain what
8-64
bits mean and what overflow means. Many languages do NOT have fixed-width numeric types. In Ruby for example, every number is arbitrary precision.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added a paragraph - is this what you wanted?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Revised and expanded again.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's better, but assume someone doesn't know what "number can be x bytes" means. I am a strong opponent to "just" explain this, especially in
about.md
, but also inintroduction.md
if it's relevant. We could add above line 16 something like:You may want to reword in your own words.
Sidenote: if you feel my or
kahgoh
's contributions are significant, feel free to add us to the contributors array when you see fit.