Skip to content

Commit

Permalink
[Concept]: Add Number-types (#360)
Browse files Browse the repository at this point in the history
* started

* updated

* Started on tests and added one more exercise

* Added third exercise, more test and updated instructions

* Added design, added blurb and fixes

* Fix line

* Added hints

* Fixes

* A bunch of fixes, major changes to test file

* A number of fixes

* Updated test file

* fix test

* Updated instructions and updated links

* Fixes, fixed path, fixed spelling, added link about phobos

* Updated based on feedback

* Changes based on feedback

* Sync linked-list docs with problem-specifications (#391)

* Sync linked-list docs with problem-specifications

The linked-list exercise has been overhauled as part of a project
to make practice exercises more consistent and friendly.

For more context, please see the discussion in the forum, as well as
the pull request that updated the exercise in the problem-specifications
repository:

- https://forum.exercism.org/t/new-project-making-practice-exercises-more-consistent-and-human-across-exercism/3943
- exercism/problem-specifications#2245

* Sync linked-list with problem-specifications

* Sync rna-transcription docs with problem-specifications (#396)

The rna-transcription exercise has been overhauled as part of a project
to make practice exercises more consistent and friendly.

For more context, please see the discussion in the forum, as well as
the pull request that updated the exercise in the problem-specifications
repository:

- https://forum.exercism.org/t/new-project-making-practice-exercises-more-consistent-and-human-across-exercism/3943
- exercism/problem-specifications#2251

* Sync largest-series-product docs with problem-specifications (#395)

* Sync largest-series-product docs with problem-specifications

The largest-series-product exercise has been overhauled as part of a project
to make practice exercises more consistent and friendly.

For more context, please see the discussion in the forum, as well as
the pull request that updated the exercise in the problem-specifications
repository:

- https://forum.exercism.org/t/new-project-making-practice-exercises-more-consistent-and-human-across-exercism/3943
- exercism/problem-specifications#2246

* Delete test cases from largest-series-product

This deletes two deprecated test cases so that we can
dramatically simplify the instructions for this exercise.

* Add diamond (#403)

* Bump actions/checkout from 3.3.0 to 3.5.2 (#402)

Bumps [actions/checkout](https://github.com/actions/checkout) from 3.3.0 to 3.5.2.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](actions/checkout@ac59398...8e5e7e5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

---------

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: Katrina Owen <[email protected]>
Co-authored-by: Ryan Hartlage <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Loading branch information
4 people authored May 28, 2023
1 parent 18e268f commit 0b399bd
Show file tree
Hide file tree
Showing 13 changed files with 514 additions and 0 deletions.
5 changes: 5 additions & 0 deletions concepts/number-types/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"blurb": "Crystal has specific number types for integers and floats. These allows you to have more control over the numbers and memory usage. Crystal has syntax for converting between these types and declaring them.",
"authors": ["meatball133"],
"contributors": ["glennj", "ihid"]
}
109 changes: 109 additions & 0 deletions concepts/number-types/about.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# Number types

Crystal has a variety of different number types for different purposes.
For example, some types are faster but have a smaller range of possible values than other types.
Some that have a larger range of possible values but are slower.

In Crystal, there are both signed and unsigned integer types.
The signed integer types can be positive or negative.
The unsigned integer types can only be positive.

## Signed integers types

These are the [signed integer types][int] in Crystal:

| Type | Size (bits) | Range |
| -------- | ----------- | ----------------------------------------------------------------------------------------------------------- |
| `Int8` | 8 | -128 to 127 |
| `Int16` | 16 | -32_768 to 32_767 |
| `Int32` | 32 | -2_147_483_648 to 2_147_483_647 |
| `Int64` | 64 | -9_223_372_036_854_775_808 to 9_223_372_036_854_775_807 |
| `Int128` | 128 | -170_141_183_460_469_231_731_687_303_715_884_105_728 to 170_141_183_460_469_231_731_687_303_715_884_105_727 |

The smaller types use less memory and are faster than the larger types but have a smaller range of possible values.

Where you know that values will be within a certain range, it is best to use the smallest type possible to save memory and improve performance.

The default integer type is `Int32`.
To declare an integer with a specific type you can use the type name as a suffix, by adding `<number>_i<bit>`.

```crystal
1_i8.class
# => Int8
```

To convert between different integer types you can use the `to_i<bit>` method.
The `to_i` method converts to the default integer type, which is `Int32`.

```crystal
1_i8.to_i16.class
# => Int16
2_i16.to_i.class
# => Int32
```

## Unsigned integers types

These the [unsigned integer][uint] types in Crystal:

`UInt8`, `UInt16`, `UInt32`, `UInt64`, `UInt128`

The only difference to signed integers is that unsigned integers can only be positive.
To declare an unsigned integer with a specific type you can use the type name as a suffix, by adding `<number>_u<bit>`.
To convert between different unsigned integer types you can use the `to_u<bit>` method.
The `to_u` method converts to the default unsigned integer type, which is `UInt32`.

```crystal
1_u8.to_u16.class
# => UInt16
```

## Floating point types

These are the floating point types in Crystal:

| Type | Size (bits) | Range |
| --------- | ----------- | -------------------- |
| `Float32` | 32 | 1.2E-38 to 3.4E+38 |
| `Float64` | 64 | 2.3E-308 to 1.7E+308 |

There are two different [floating point types][float], one is more precise than the other.

The default floating point type is `Float64`.

To convert between different floating point types you can use the `to_f<bit>` method.
The `to_f` method converts to the default floating point type, which is `Float64`.

## Type after an operation

When you execute an operation between two numbers, the result will be of the type of the number with the highest precision.
Float is more precise than an integer and an integer is more precise than an unsigned integer.
Then `Float64` is more precise than Float32 and so on.

```crystal
(1_u8 + 2_u64).class
# => UInt64
(1_u8 + 2_i64).class
# => Int64
(1_u8 + 2.0_f64).class
# => Float64
```

## Dig Deeper: unsigned integers vs signed integers

```exercism/advanced
Under the hood, what differentiates unsigned and signed integers is that signed integers use the first bit to store the sign.
The sign is either positive or negative.
For unsigned integers, the first bit is used to store the value.
So for a signed 32-bit integer is the max value 2^31 - 1.
For an unsigned 32-bit integer is the max value 2^32 - 1.
If you are interested in learning more about signedness you can read more about it on [Wikipedia](https://en.wikipedia.org/wiki/Signedness).
```

[float]: https://crystal-lang.org/api/latest/Float.html
[int]: https://crystal-lang.org/api/latest/Int.html
[uint]: https://crystal-lang.org/api/latest/UInt32.html
80 changes: 80 additions & 0 deletions concepts/number-types/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Number types

Crystal has a variety of different number types for different purposes.
For example, some types are faster but have a smaller range of possible values than other types.
Some that have a larger range of possible values but are slower.

In Crystal, there are both signed and unsigned integer types.
The signed integer types can be positive or negative.
The unsigned integer types can only be positive.

## Signed integers types

These are the [signed integer types][int] in Crystal:

| Type | Size (bits) | Range |
| -------- | ----------- | ----------------------------------------------------------------------------------------------------------- |
| `Int8` | 8 | -128 to 127 |
| `Int16` | 16 | -32_768 to 32_767 |
| `Int32` | 32 | -2_147_483_648 to 2_147_483_647 |
| `Int64` | 64 | -9_223_372_036_854_775_808 to 9_223_372_036_854_775_807 |
| `Int128` | 128 | -170_141_183_460_469_231_731_687_303_715_884_105_728 to 170_141_183_460_469_231_731_687_303_715_884_105_727 |

The smaller types use less memory and are faster than the larger types but have a smaller range of possible values.

Where you know that values will be within a certain range, it is best to use the smallest type possible to save memory and improve performance.

The default integer type is `Int32`.
To declare an integer with a specific type you can use the type name as a suffix, by adding `<number>_i<bit>`.

```crystal
1_i8.class
# => Int8
```

To convert between different integer types you can use the `to_i<bit>` method.
The `to_i` method converts to the default integer type, which is `Int32`.

```crystal
1_i8.to_i16.class
# => Int16
2_i16.to_i.class
# => Int32
```

## Unsigned integers types

These the [unsigned integer][uint] types in Crystal:

`UInt8`, `UInt16`, `UInt32`, `UInt64`, `UInt128`

The only difference to signed integers is that unsigned integers can only be positive.
To declare an unsigned integer with a specific type you can use the type name as a suffix, by adding `<number>_u<bit>`.
To convert between different unsigned integer types you can use the `to_u<bit>` method.
The `to_u` method converts to the default unsigned integer type, which is `UInt32`.

```crystal
1_u8.to_u16.class
# => UInt16
```

## Floating point types

These are the floating point types in Crystal:

| Type | Size (bits) | Range |
| --------- | ----------- | -------------------- |
| `Float32` | 32 | 1.2E-38 to 3.4E+38 |
| `Float64` | 64 | 2.3E-308 to 1.7E+308 |

There are two different [floating point types][float], one is more precise than the other.

The default floating point type is `Float64`.

To convert between different floating point types you can use the `to_f<bit>` method.
The `to_f` method converts to the default floating point type, which is `Float64`.

[float]: https://crystal-lang.org/api/latest/Float.html
[int]: https://crystal-lang.org/api/latest/Int.html
[uint]: https://crystal-lang.org/api/latest/UInt32.html
14 changes: 14 additions & 0 deletions concepts/number-types/links.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[
{
"url": "https://en.wikipedia.org/wiki/Signedness",
"description": "Wikipedia: Signedness"
},
{
"url": "https://crystal-lang.org/reference/latest/syntax_and_semantics/literals/floats.html",
"description": "Crystal docs: Float"
},
{
"url": "https://crystal-lang.org/reference/latest/syntax_and_semantics/literals/integers.html",
"description": "Crystal docs: Int"
}
]
13 changes: 13 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@
],
"status": "wip"
},
{
"slug": "navigation-computer",
"name": "Navigation Computer",
"uuid": "d980412c-1480-453a-be6c-2cd7779284bc",
"concepts": ["number-types"],
"prerequisites": ["numbers"],
"status": "wip"
},
{
"slug": "wellingtons-weather-station",
"name": "Wellington's Weather Station",
Expand Down Expand Up @@ -919,6 +927,11 @@
"slug": "bools",
"name": "Bools"
},
{
"uuid": "43dd66b4-5d26-44b6-8f2e-2a0392c642b2",
"slug": "number-types",
"name": "Number Types"
},
{
"uuid": "4aa0a83d-393a-412e-8175-65bbf7fcd8d6",
"slug": "numbers",
Expand Down
24 changes: 24 additions & 0 deletions exercises/concept/navigation-computer/.docs/hints.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Hints

## General

- Declaring a numeral with a specific type is done by appending the type to the numeral, e.g. `42_u8` for an unsigned 8-bit integer.
- Converting between different types is done by calling the `to_<type>` method on the numeral, e.g. `42u8.to_u16` for an unsigned 16-bit integer.

## 1. Navigation constants

- You need to define [constants][constants] that should contain a [integer][integers].
- The constant should be declared inside the `Navigation` class.
- The constant needs to be declared outside of any method.

## 2. Correct area analysis

- You need to convert the input to an unsigned integer.

## 3. Calculate the velocity

- To get the velocity you need to divide the distance by the time.
- The result of a numeric operation will be of the highest precision type, so you need to convert the result to the correct type.

[constants]: https://crystal-lang.org/reference/syntax_and_semantics/constants.html
[integers]: https://crystal-lang.org/reference/latest/syntax_and_semantics/literals/integers.html
65 changes: 65 additions & 0 deletions exercises/concept/navigation-computer/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Instructions

The ESA (Exercism Space Agency) is at full speed in planning a new mission to [Phobos][phobos], a moon of Mars.
The mission's goal is to land a probe on the surface of Phobos and to send back data about the surface.
ESA has requested your help to build the navigation computer for the probe.
The navigation computer has limited memory so we need to keep the memory usage as low as possible.
Thereby we need to use the right data types.

## 1. Navigation constants

The navigation computer needs to know the distance between some objects in space to do the right calculations, the distance is measured in km.

Define the following constants:

- `NEPTUNE_DISTANCE` with the value `4_400_000_000` which should be stored as a `Int64`
- `MARS_DISTANCE` with the value `227_940_000` which should be stored as a `Int32`
- `ATMOSPHERE_DISTANCE` with the value `10_000` which should be stored as a `Int16`

## 2. Correct area analysis

The navigation computer needs to know the area of some objects in space to do the right calculations.
An area can **NOT** be negative.
The engineers had the plan that the program would generate an overflow error when the area is negative.
But the engineers forgot to change the signed integer to an unsigned integer.

Thereby the engineers would like a program that converts the signed integer to an unsigned integer.

Implement the `Navigation#correct_area_analysis` method that takes a `measurement` as an argument and returns the area as an unsigned integer with 32 bits.

```crystal
measurement = 52554
measurement.class
# => Int32
Navigation.new.correct_area_analysis(measurement)
# => 52554
Navigation.new.correct_area_analysis(measurement).class
# => UInt32
```

## 3. Calculate the velocity

The navigation computer needs to know the velocity of the probe.
The velocity is measured in m/s.

To get the velocity we need to know the distance and the time it took to travel that distance.
Then take the distance and divide it by the time.

The velocity doesn't have to be super accurate and will never be a big number, therefore we can use a `Float32`.

Implement the `Navigation#calculate_velocity` method that takes `distance` and `time` as arguments and returns the velocity as a `Float` with 32 bits.

```crystal
distance = 52554
time = 2.5
Navigation.new.calculate_velocity(distance, time)
# => 21021.6
Navigation.new.calculate_velocity(distance, time).class
# => Float32
```

[phobos]: https://en.wikipedia.org/wiki/Phobos_(moon)
Loading

0 comments on commit 0b399bd

Please sign in to comment.