-
-
Notifications
You must be signed in to change notification settings - Fork 204
Port exercise/cars assemble #713
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?
Changes from all commits
b454702
8675412
a80986c
7a1d11a
083d2e1
6074bb1
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,154 @@ | ||
| # 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. | ||
|
|
||
| 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). | ||
| - Unsigned integers have a `U` prefix: `UByte`, `UShort`, `UInt` or `ULong`. | ||
|
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. We should explain signed versus unsigned at some point before this. 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. There isn't much "before", so I tried to clarify these bullets. 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 am now reviewing this and I saw that is a suggestion I already made on the concept doc. |
||
| - 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`. | ||
|
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. Would students be expected to know what type inference is by this 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. Yes, it was in |
||
|
|
||
| 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. | ||
|
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. conventional relative to what? What makes them a hexadecimal or binary literal specifically? 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 am now reviewing this and I saw that is a suggestion I already made on the concept doc. |
||
| 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][wiki-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 | ||
| [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 | ||
| [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 | ||
| 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. | ||
| 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/ |
| 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" | ||
| } | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| # Hints | ||
|
|
||
| ## General | ||
|
|
||
| - To learn more about type conversions in Kotlin, check [Explicit number conversions][type conversions]. | ||
|
|
||
| ## 1. Calculate the number of working cars produced per hour | ||
|
|
||
| - The percentage (passed as an argument) is a number between 0-100. To make this percentage a bit easier to work with, start by dividing it by 100. | ||
| - To compute the number of cars produced successfully, multiply the percentage (divided by 100) by the number of cars produced. | ||
|
|
||
| ## 2. Calculate the number of working cars produced per minute | ||
|
|
||
| - Start by calculating the production of successful cars per hour. For this, you can use the function you implemented from the previous step. | ||
| - Knowing the production per hour of cars, you can get the production per minute by dividing the production per hour by 60 (the number of minutes in an hour). | ||
| - Remember to cast the result to an `Int` | ||
|
|
||
| ## 3. Calculate the cost of production | ||
|
|
||
| - Start by working out how many groups of 10 cars there are. You can do this by dividing the number of cars by 10. | ||
| - Then work out how many cars are remaining (the [modulo operator][modulo operator] is useful for this). | ||
| - To arrive at the cost, multiply the number of groups by the cost to produce 10 cars and then multiply the number of cars remaining by the cost to produce each individual car. Then sum the results of the multiplication together. | ||
|
|
||
| [type conversions]: https://kotlinlang.org/docs/numbers.html#explicit-number-conversions | ||
| [modulo operator]: https://www.baeldung.com/kotlin/integer-division-modulus |
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.
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'll make changes in PR #711 (I can't edit this PR)