Skip to content

Commit

Permalink
[Free Lancer Rates]: Reworked (#642)
Browse files Browse the repository at this point in the history
* Update instructions.md

* Fix examples

* Update about.md

* New concepts text

* Various improvements

* Fixes
  • Loading branch information
meatball133 authored Aug 2, 2023
1 parent 9b00995 commit ce0043a
Show file tree
Hide file tree
Showing 12 changed files with 442 additions and 169 deletions.
3 changes: 2 additions & 1 deletion concepts/numbers/.meta/config.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"blurb": "The two most commonly used number types in Swift are 'Int' and 'Double'.",
"authors": [
"wneumann"
"wneumann",
"meatball133"
],
"contributors": []
}
154 changes: 89 additions & 65 deletions concepts/numbers/about.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,105 +2,129 @@

## Numbers

Swift contains many basic numeric types that can represent sets of either integer or floating-point values, where different types may be chosen depending on the size of value you require and the architecture of the computer where the application is running (e.g. 32-bit or 64-bit).
Swift has 2 main types of numbers: integers and floating-point numbers.
[Integers][integers] are whole numbers, e.g. `0`, `1`, `-1`, `42`, and `-273`.
[Floating-point numbers][floatingpoint] are numbers with a fractional component, e.g. `0.0`, `3.14`, and `-1.36969e-10`.
Swift also allows using underscores to make numbers more readable, e.g. `1_000_000` is the same as `1000000`.
Floating-points can be written in either decimal or exponential notation.

## Integer types:
In most cases you would define the type for integers as [`Int`][int] and for floating-point numbers as [`Double`][double].

Swift offers signed and unsigned integer types in 8, 16, 32, and 64 bit sizes named `IntX` or `UIntX` where _X_ is the number of bits and a leading U specifies unsigned integers. Swift also offers the `Int` and `UInt` types which are the signed and unsigned integers with a number of bits equal to the native machine word size (64 bits on most modern computers).
To declare a variable or constant to be of type `Int` or `Double`, you can use a type annotation:

The default integer type in Swift is `Int`, and it is preferred to use `Int` rather than `UInt` even if you know that your values will be non-negative unless you specifically need values larger than the maximum `Int` value (`2147483647` on 32 bit systems `9223372036854775807` on 64 bit systems. According to Apple,
```swift
let speed: Int = 42 // speed is an Int
let pi: Double = 3.14 // pi is a Double
let giga: Double = 1_000_000_000 // giga is a Double
let plancksConstant : Double = 6.62607015e-34 // plancksConstant is a Double
```

> A consistent use of Int for integer values aids code interoperability, avoids the need to convert between different number types, and matches integer type inference
## Arithmetic operators

You can read more about integer types in [A Tour of Swift: Integers][integers].
```exercism/caution
In Swift can't mix types in arithmetic operations, so you can't use any arithmetic operator on an `Int` with a `Double` or vice versa.
Thereby you have to do a type conversion first.
```

## Floating-point
Swift does have a set of [arithmetic operators][arithmetic-operators] that can be used to perform basic mathematical operations.
The `+` operator is used for addition, the `-` operator is used for subtraction, and the `*` operator is used for multiplication.

Floating-point number types are used to represent numbers which may have a fractional component, e.g. `0.0`, `3.14`, and `-1.36969e-10`. Swift offers two floating-point number types: `Double` and `Float`. `Double` is a 64-bit floating point type and `Float` is a 32-bit floating bit type. Like with `Int` for the integer types, it is preferred to use `Double` as the default floating point type. According to Apple:
| Operator | Example |
| -------- | ----------------------- |
| `+` | `4 + 6 // equals 10` |
| `-` | `15 - 10 // equals 5` |
| `*` | `2 * 3 // equals 6` |

> Double has a precision of at least 15 decimal digits, whereas the precision of Float can be as little as 6 decimal digits. The appropriate floating-point type to use depends on the nature and range of values you need to work with in your code. In situations where either type would be appropriate, Double is preferred.
### Division

You can read more about floating-point types in [A Tour of Swift: Floating-Point Numbers][floatingpoint].
The `/` operator is used for division.
When using a floating-point number, the result will be a floating-point number.
When using integers, the result will be an integer.

## Arithmetic operators

Swift supports the standard set of arithmetic operators of `+`, `-`, `*`, `/` and `%` (remainder not modulo). Note that for `Int` values, `/` is the integer division operator that throws away any remainder.
```swift
5 / 2.0 // equals 2.5
5 / 2 // equals 2
```

You can read more about the arithmetic operators in [A Tour of Swift: Arithmetic Operators][arithmeticoperators].
When dividing by zero, depending on the type of number, you will get a different result.
If you divide a floating-point number by zero, the result will be `inf`, or `-inf` if the number being divided is negative.
Only exception is when you divide zero by zero, and one of them being a floating point number which will result in `nan`.
If you divide an integer by zero, you will get a compile error.

## Comparison operators
```swift
print(5.0 / 0.0) // Prints inf
print(-5.0 / 0.0) // Prints -inf
print(0.0 / 0.0) // Prints nan

Swift also supports the standard set of comparison operators that are seen in C. Swift uses `!=` to test for inequality and not `<>` as in some languages. As with other languages, care should be taken when comparing two floating point values for equality.
// The following code will not compile
print(5 / 0) // error: division by zero
```

You can read more about the arithmetic operators in [A Tour of Swift: Comparison Operators][comparisonoperators].
### Remainder

## Type inference
The [`%` operator][reminder-operator] is used to get the remainder of a division and does only work with integers.
The operator returns the remainder of the division of the first argument by the second argument.
And as with division, having the second argument having the value of zero will result in a compile error.

When a number is written as a whole number in Swift code, without any additional context to steer the type inference engine in the right direction, the Swift compiler will assume that number is an `Int`. If you want to tell the compiler that you want it to be a `Double` you must use either a type annotation or append a .0 onto the end of the number literal. E.g.
```exercism/note
In other languages, is this operator also known as the modulo operator.
But in Swift, it does not work the same way as the modulo operator, since it strictly speaking, returns the remainder, not the modulo.
```

```swift
let x = 42 // x is an Int
let y = 42.0 // y is a Double
let z: Double = 42 // z is a Double
5 % 2 // equals 1
-5 % 2 // equals -1

// The following code will not compile
5 % 0 // error: division by zero
```

You can read more about this in [A Tour of Swift: Type Safety and Inference][typeinference].
## Rounding numbers

## Numeric Literals
Rounding numbers is done by using the `rounded()` method on a floating-point number.
To round to the nearest integer, you can use the `rounded()` method without any arguments.
To round up or down, you can use the `rounded(.up)` or `rounded(.down)` methods respectively.

```swift
let x = 3.14
let y = x.rounded() // y equals 3.0
let w = x.rounded(.down) // w equals 3.0
let z = x.rounded(.up) // z equals 4.0
```

Integers in Swift may be typed out in many ways, including as decimals, hexadecimals, binary, or octal numbers. Floating-point numbers may be typed in decimal or hexadecimal.
## Type inference

Numeric literals may also include the underscore character (`_`) which is used to group numbers and improve readability. E.g. rather than write `18093402034`, one can more clearly write `18_093_402_034`.
Swift can [infer what type][typeinference] a number is based on the context, without extra context will the compiler assume that number is an `Int`.
If you want to tell the compiler that you want a whole number to be a `Double` you must use either a type annotation or append a `.0` onto the end of the number literal. E.g.

For specifics on numeric literals in Swift, read [A Tour of Swift: Numeric Literals][numericliterals].
```swift
let x = 42 // x is an Int
let y = 42.0 // y is a Double
let z: Double = 42 // z is a Double
```

## Type Conversion

In Swift, assignment of a value between different types requires explicit conversion. For example, to convert an `Int` to a `Double` and vice versa, you would need to do the following:
In Swift, to convert a value from one type to another, you need to do a [type Conversion][type-conversion].
For example, to convert an `Int` to a `Double` and vice versa, you would need to do the following:

```swift
let x = 42
let d = Double(x)
print(d) // Prints 42.0
print(type(of: d)) // Prints Double

let pi = Double.pi
let pi = 3.14
let iPi = Int(pi)

print("x:", x, "is of type:", type(of: x))
// Output: x: 42 is of type: Int

print("d:", d, "is of type:", type(of: d))
// Output: d: 42.0 is of type: Double

print("pi:", pi, "is of type:", type(of: pi))
// Output: pi: 3.141592653589793 is of type: Double

print("iPi:", iPi, "is of type:", type(of: iPi))
// Output: fiPi: 3 is of type: Int
```

Note that in some cases, where the value is out of range for the target type, attempting to convert types will lead to an error. If the compiler can detect the problem, the code will fail to compile, otherwise, a runtime error will occur. E.g.

```swift
let tooBigByte = Int8(300)
// Compiler error: Integer literal '300' overflows when stored into 'Int8'

let negativeUInt = UInt(-1)
// Compiler error: Negative integer '-1' overflows when stored into unsigned type 'UInt'

let big = 300
let tooBigByte2 = Int8(big)
// error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).

let negative = -1
let negativeUInt2 = UInt(negative)
// error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
print(iPi) // Prints 3
print(type(of: iPi)) // Prints Int
```

[integers]: https://docs.swift.org/swift-book/LanguageGuide/TheBasics.html#ID317
[floatingpoint]: https://docs.swift.org/swift-book/LanguageGuide/TheBasics.html#ID321
[integers]: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/thebasics/#Integers
[floatingpoint]: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/thebasics/#Floating-Point-Numbers
[int]: https://developer.apple.com/documentation/swift/int
[double]: https://developer.apple.com/documentation/swift/double
[arithmeticoperators]: https://docs.swift.org/swift-book/LanguageGuide/BasicOperators.html#ID63
[comparisonoperators]: https://docs.swift.org/swift-book/LanguageGuide/BasicOperators.html#ID70
[typeinference]: https://docs.swift.org/swift-book/LanguageGuide/TheBasics.html#ID322
[numericliterals]: https://docs.swift.org/swift-book/LanguageGuide/TheBasics.html#ID323
[arithmetic-operators]: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/basicoperators/#Arithmetic-Operators
[reminder-operator]: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/basicoperators/#Remainder-Operator
[typeinference]: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/thebasics/#Type-Safety-and-Type-Inference
[type-conversion]: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/thebasics/#Integer-and-Floating-Point-Conversion
125 changes: 118 additions & 7 deletions concepts/numbers/introduction.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,130 @@
# Introduction
# About

Swift contains many basic numeric types that can represent sets of either integer or floating-point values, where different types may be chosen depending on the size of value you require and the architecture of the computer where the application is running (e.g. 32-bit or 64-bit).
## Numbers

For this exercise you will only be dealing with the two most commonly used numeric types in Swift:
Swift has 2 main types of numbers: integers and floating-point numbers.
[Integers][integers] are whole numbers, e.g. `0`, `1`, `-1`, `42`, and `-273`.
[Floating-point numbers][floatingpoint] are numbers with a fractional component, e.g. `0.0`, `3.14`, and `-1.36969e-10`.
Swift also allows using underscores to make numbers more readable, e.g. `1_000_000` is the same as `1000000`.
Floating-points can be written in either decimal or exponential notation.

- `Int`: This type is used to represent signed whole numbers e.g. `0`, `255`, `2147483647`. A signed integer is at least 32 bits in size (value range of: -2147483648 through 2147483647). But this will depend on the systems architecture. Most modern computers are 64 bit, therefore `Int` will be 64 bits in size (value range of: -9223372036854775808 through 9223372036854775807).
In most cases you would define the type for integers as [`Int`][int] and for floating-point numbers as [`Double`][double].

- `Double`: This type is a 64 bit floating-point type, used to represent numbers which may have a fractional component, e.g. `0.0`, `3.14`, and `-1.36969e-10`.
To declare a variable or constant to be of type `Int` or `Double`, you can use a type annotation:

Swift supports the standard set of arithmetic operators of `+`, `-`, `*`, `/` and `%` (remainder not modulo). Note that for `Int` values, `/` is the integer division operator that throws away any remainder.
```swift
let speed: Int = 42 // speed is an Int
let pi: Double = 3.14 // pi is a Double
let giga: Double = 1_000_000_000 // giga is a Double
let plancksConstant : Double = 6.62607015e-34 // plancksConstant is a Double
```

## Arithmetic operators

```exercism/caution
In Swift can't mix types in arithmetic operations, so you can't use any arithmetic operator on an `Int` with a `Double` or vice versa.
Thereby you have to do a type conversion first.
```

Swift does have a set of [arithmetic operators][arithmetic-operators] that can be used to perform basic mathematical operations.
The `+` operator is used for addition, the `-` operator is used for subtraction, and the `*` operator is used for multiplication.

| Operator | Example |
| -------- | ----------------------- |
| `+` | `4 + 6 // equals 10` |
| `-` | `15 - 10 // equals 5` |
| `*` | `2 * 3 // equals 6` |

### Division

The `/` operator is used for division.
When using a floating-point number, the result will be a floating-point number.
When using integers, the result will be an integer.

```swift
5 / 2.0 // equals 2.5
5 / 2 // equals 2
```

When dividing by zero, depending on the type of number, you will get a different result.
If you divide a floating-point number by zero, the result will be `inf`, or `-inf` if the number being divided is negative.
Only exception is when you divide zero by zero, and one of them being a floating point number which will result in `nan`.
If you divide an integer by zero, you will get a compile error.

```swift
print(5.0 / 0.0) // Prints inf
print(-5.0 / 0.0) // Prints -inf
print(0.0 / 0.0) // Prints nan

// The following code will not compile
print(5 / 0) // error: division by zero
```

### Remainder

The [`%` operator][reminder-operator] is used to get the remainder of a division and does only work with integers.
The operator returns the remainder of the division of the first argument by the second argument.
And as with division, having the second argument having the value of zero will result in a compile error.

When a number is written as a whole number in Swift code, without any additional context to steer the type inference engine in the right direction, the Swift compiler will assume that number is an `Int`. If you want to tell the compiler that you want it to be a `Double` you must use either a type annotation or append a .0 onto the end of the number literal. E.g.
```exercism/note
In other languages, is this operator also known as the modulo operator.
But in Swift, it does not work the same way as the modulo operator, since it strictly speaking, returns the remainder, not the modulo.
```

```swift
5 % 2 // equals 1
-5 % 2 // equals -1

// The following code will not compile
5 % 0 // error: division by zero
```

## Rounding numbers

Rounding numbers is done by using the `rounded()` method on a floating-point number.
To round to the nearest integer, you can use the `rounded()` method without any arguments.
To round up or down, you can use the `rounded(.up)` or `rounded(.down)` methods respectively.

```swift
let x = 3.14
let y = x.rounded() // y equals 3.0
let w = x.rounded(.down) // w equals 3.0
let z = x.rounded(.up) // z equals 4.0
```

## Type inference

Swift can [infer what type][typeinference] a number is based on the context, without extra context will the compiler assume that number is an `Int`.
If you want to tell the compiler that you want a whole number to be a `Double` you must use either a type annotation or append a `.0` onto the end of the number literal. E.g.

```swift
let x = 42 // x is an Int
let y = 42.0 // y is a Double
let z: Double = 42 // z is a Double
```

## Type Conversion

In Swift, to convert a value from one type to another, you need to do a [type Conversion][type-conversion].
For example, to convert an `Int` to a `Double` and vice versa, you would need to do the following:

```swift
let x = 42
let d = Double(x)
print(d) // Prints 42.0
print(type(of: d)) // Prints Double

let pi = 3.14
let iPi = Int(pi)
print(iPi) // Prints 3
print(type(of: iPi)) // Prints Int
```

[integers]: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/thebasics/#Integers
[floatingpoint]: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/thebasics/#Floating-Point-Numbers
[int]: https://developer.apple.com/documentation/swift/int
[double]: https://developer.apple.com/documentation/swift/double
[arithmetic-operators]: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/basicoperators/#Arithmetic-Operators
[reminder-operator]: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/basicoperators/#Remainder-Operator
[typeinference]: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/thebasics/#Type-Safety-and-Type-Inference
[type-conversion]: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/thebasics/#Integer-and-Floating-Point-Conversion
31 changes: 30 additions & 1 deletion concepts/numbers/links.json
Original file line number Diff line number Diff line change
@@ -1 +1,30 @@
[]
[
{
"url": "https://docs.swift.org/swift-book/documentation/the-swift-programming-language/thebasics/#Integers",
"description": "Swift Book: Integers"
},
{
"url": "https://docs.swift.org/swift-book/documentation/the-swift-programming-language/thebasics/#Floating-Point-Numbers",
"description": "Swift Book: Floating-Point Numbers"
},
{
"url": "https://docs.swift.org/swift-book/documentation/the-swift-programming-language/basicoperators/#Arithmetic-Operators",
"description": "Swift Book: Arithmetic Operators"
},
{
"url": "https://docs.swift.org/swift-book/documentation/the-swift-programming-language/basicoperators/#Remainder-Operator",
"description": "Swift Book: Remainder Operator"
},
{
"url": "https://docs.swift.org/swift-book/documentation/the-swift-programming-language/thebasics/#Integer-and-Floating-Point-Conversion",
"description": "Swift Book: Integer and Floating-Point Conversion"
},
{
"url": "https://developer.apple.com/documentation/swift/int",
"description": "Swift docs: Int"
},
{
"url": "https://developer.apple.com/documentation/swift/double",
"description": "Swift docs: Double"
}
]
Loading

0 comments on commit ce0043a

Please sign in to comment.