|
1 |
| -# Haskell Built-in Numeric Types |
| 1 | +# Numbers |
2 | 2 |
|
3 |
| -## Numbers |
4 |
| - |
5 |
| -Haskell's standard library, known as ***Prelude***, defines most basic numeric types: fixed sized integers (`Int`), arbitrary precision integers (`Integer`), single precision floating (`Float`), and double precision floating (`Double`). |
6 |
| -Other numeric types such as rationals and complex numbers are defined in additional libraries. |
| 3 | +Haskell has a type, `Num`, which is the base type for all numeric types. |
| 4 | +There are four main sub-types inside the Number type: [`Int`][int], [`Integer`][integer], [`Double`][double] and [`Float`][float]. |
7 | 5 |
|
| 6 | +There are two types of integers types in Haskell, which represents whole numbers. |
| 7 | +`Int` is a fixed-size integer, while `Integer` is an arbitrary precision integer. |
8 | 8 | `Integer`s hold any number no matter how big, up to the limit of your machine's memory, while `Int` corresponds to the set of positive and negative integers that can be expressed in 32 or 64 bits (guaranteed at least -2^29 to 2^29).
|
9 | 9 |
|
| 10 | +Note that when writting negative numbers, you should use parentheses to avoid ambiguity. |
| 11 | + |
| 12 | +```haskell |
| 13 | +1 |
| 14 | + |
| 15 | +(-1) |
| 16 | +``` |
| 17 | + |
10 | 18 | `Float` corresponds to the set of real numbers, limited by the precision of the computer.
|
11 | 19 | Operations defined on numbers usually work on one type or the other, but not both.
|
| 20 | +`Double` is a floating-point number with double precision. |
| 21 | + |
| 22 | +```haskell |
| 23 | +10.5 |
| 24 | +``` |
| 25 | + |
| 26 | +## Converting between integers and floats |
| 27 | + |
| 28 | +Using the `toFloat` function, allows you to convert an `Int` or `Integer` to a `Float`. |
| 29 | + |
| 30 | +```haskell |
| 31 | +toFloat 1 |
| 32 | +-- -> 1.0 |
| 33 | +``` |
| 34 | + |
| 35 | +There is also `fromIntegral` which converts any number types to the inferred type number type needed. |
| 36 | + |
| 37 | +```haskell |
| 38 | +fromIntegral 1 |
| 39 | +-- -> 1.0 |
| 40 | +``` |
| 41 | + |
| 42 | +To convert a `Float` to an `Int`, you can use the `round`, `floor`, or `ceiling` functions. |
| 43 | +The `round` function rounds to the nearest integer, `floor` rounds down, and `ceiling` rounds up. |
| 44 | + |
| 45 | +```haskell |
| 46 | +round 1.5 |
| 47 | +-- -> 2 |
| 48 | + |
| 49 | +floor 1.5 |
| 50 | +-- -> 1 |
12 | 51 |
|
13 |
| -Functions to convert between `Float` and `Integer` include, among others, `toFloat` which converts `Int`/`Integer` to `Float` and `ceiling` which converts a `Float` to an `Int`. |
| 52 | +ceiling 1.5 |
| 53 | +-- -> 2 |
| 54 | +``` |
14 | 55 |
|
15 | 56 | ## Arithmetic operators
|
16 | 57 |
|
17 |
| -Haskell has three "raise to the power" operators which work differently and take different argument types. |
| 58 | +You can use the [basic arithmetic operators][math] on the numeric types. |
| 59 | +The operators are `+`, `-`, `*`, `/`, and `%`. |
| 60 | +When using these operators, the types of the numbers must match. |
| 61 | +The `fromIntegral` function will convert so that the types match. |
18 | 62 |
|
19 |
| -- `**` Takes two **floating point numbers** and uses logarithms to compute the power. |
20 |
| -- `^^` Takes a **floating point** and raises it to a positive or negative **integer** power. |
21 |
| -- `^` Takes **any numerical type** and raises it to a **positive integer** power. |
| 63 | +### Addition & Subtraction & Multiplication |
| 64 | + |
| 65 | +The `+` operator is used for addition, the `-` operator is used for subtraction, and the `*` operator is used for multiplication. |
22 | 66 |
|
23 |
| -Conversion from an integer type (`Int` or `Integer`) to any other numeric type is done using the function `fromIntegral`. |
24 |
| -The target type is inferred automatically. |
25 |
| -For example: |
| 67 | +| Operator | Example | |
| 68 | +| -------- | -------------- | |
| 69 | +| `+` | `4 + 6 => 10` | |
| 70 | +| `-` | `15 - 10 => 5` | |
| 71 | +| `*` | `2 * 3 => 6` | |
| 72 | + |
| 73 | +### Division |
| 74 | + |
| 75 | +Division is used to divide numbers. |
| 76 | +The `/` operator is used for division. |
| 77 | +The result will always be a float. |
26 | 78 |
|
27 | 79 | ```haskell
|
28 |
| -n :: Integer |
29 |
| -n = 6 |
30 |
| -x :: Float |
31 |
| -x = fromIntegral n --> x = 6.0 |
32 |
| - |
33 |
| -m :: Int |
34 |
| -m = 7 |
35 |
| -y :: Double |
36 |
| -y = fromIntegral m --> y = 7.0 |
| 80 | +4.0 / 2.5 |
| 81 | +-- -> 1.6 |
| 82 | + |
| 83 | +4 / 2 |
| 84 | +-- -> 2.0 |
37 | 85 | ```
|
38 | 86 |
|
39 |
| -Division of integers is a little complicated. |
40 |
| -If you use the ordinary `/` operator on integers, then you will get an error message (although the expression `4/3` does work because Haskell helpfully promotes literal integers to floats where necessary). |
41 |
| -Instead, integer division is done using a collection of named operators. |
| 87 | +~~~~exercism/caution |
| 88 | +In some programming languages, when dividing by zero, the result will be an error. |
42 | 89 |
|
43 |
| -Haskell has a neat trick with operators: you can take any function that takes two arguments and use it like an operator by enclosing the name in back-ticks. |
44 |
| -So the following two lines mean exactly the same thing: |
| 90 | +In Haskell, when dividing by zero, the result is `Infinity` or `-Infinity`. |
| 91 | +The only exception is dividing zero by zero, resulting in `NaN` (Not a Number). |
45 | 92 |
|
46 | 93 | ```haskell
|
47 |
| - d = 7 `div` 3 |
48 |
| - d = div 7 3 |
| 94 | +1 / 0 |
| 95 | +-- -> Infinity |
| 96 | +
|
| 97 | +(-1) / 0 |
| 98 | +-- -> -Infinity |
| 99 | +
|
| 100 | +0 / 0 |
| 101 | +-- -> NaN |
| 102 | +``` |
| 103 | +~~~~ |
| 104 | + |
| 105 | +## Integer division |
| 106 | + |
| 107 | +Integer division is used to divide numbers and get the whole part of the result. |
| 108 | +The result will always be rounded down to an Int. |
| 109 | + |
| 110 | +```haskell |
| 111 | +2 `div` 2 |
| 112 | +-- -> 2 |
| 113 | + |
| 114 | +5 `div` 2 |
| 115 | +-- -> 2 |
49 | 116 | ```
|
50 | 117 |
|
51 |
| -With that in mind, here are the integer division operators: |
| 118 | +~~~~exercism/caution |
| 119 | +Dividing by zero when using integer division results in a Exception. |
| 120 | +This is different from normal division. |
| 121 | +~~~~ |
| 122 | + |
| 123 | +### Modulus |
52 | 124 |
|
53 |
| -- `quot`: Returns the quotient of the two numbers. |
54 |
| - This is the result of division which is then truncated towards zero. |
55 |
| -- `rem`: Returns the remainder from the quotient. |
56 |
| -- `div`: Similar to `quot`, but is rounded down towards minus infinity. |
57 |
| -- `mod`: Returns the modulus of the two numbers. |
58 |
| - This is similar to `rem`, but has different rules when `div` returns a negative number. |
| 125 | +Modulus is used to get the remainder of a division. |
| 126 | +The `mod` operator is used for modulus. |
59 | 127 |
|
60 |
| -Just as you can convert a function with two arguments into an operator, you can convert an operator into a function with two arguments by putting it in parentheses. |
61 |
| -So the following two lines mean the same thing: |
| 128 | +```haskell |
| 129 | +5 `mod` 2 |
| 130 | +-- -> 1 |
| 131 | + |
| 132 | +5 `mod` 3 |
| 133 | +-- -> 2 |
| 134 | +``` |
| 135 | + |
| 136 | +~~~~exercism/caution |
| 137 | +Dividing by zero when using modulo results in an Exception. |
| 138 | +This is different from normal division. |
62 | 139 |
|
63 | 140 | ```haskell
|
64 |
| -(+) 3 4 |
65 |
| -3 + 4 |
| 141 | +1 `mod` 0 |
| 142 | +# Exception: divide by zero |
| 143 | +``` |
| 144 | +~~~~ |
| 145 | + |
| 146 | +## Exponentiation |
| 147 | + |
| 148 | +Haskell has three "raise to the power" operators which work differently and take different argument types. |
| 149 | + |
| 150 | +- `**` Takes two **floating point numbers** and uses logarithms to compute the power. |
| 151 | +- `^^` Takes a **floating point** and raises it to a positive or negative **integer** power. |
| 152 | +- `^` Takes **any numerical type** and raises it to a **positive integer** power. |
| 153 | + |
| 154 | +```haskell |
| 155 | +3.0 ** 2.1 |
| 156 | +-- -> 10.04510856630514 |
| 157 | + |
| 158 | +2.5 ^^ 2 |
| 159 | +-- -> 6.25 |
| 160 | + |
| 161 | +2 ^ 3 |
| 162 | +-- -> 8 |
| 163 | +``` |
| 164 | + |
| 165 | +## Priority and parentheses |
| 166 | + |
| 167 | +Haskell allows parentheses(`()`), which can be used to group expressions. |
| 168 | +This is useful when you want to change the order of operations. |
| 169 | + |
| 170 | +When using multiple arithmetic operators, the order of operations is the same as in mathematics, also known as [PEMDAS][pemdas]. |
| 171 | +It follows the order of parentheses(`()`), exponents(`**`), multiplication(`*`) and division(`/`), and addition(`+`) and subtraction(`-`). |
| 172 | + |
| 173 | +```haskell |
| 174 | +2 + 3 - 4 * 4 |
| 175 | +-- -> -11 |
| 176 | + |
| 177 | +(2 + 3 - 4) * 4 |
| 178 | +-- -> 4 |
66 | 179 | ```
|
67 | 180 |
|
68 |
| ---- |
69 |
| -### Credits: |
70 |
| -The above text is modified from __The Haskell 98 Report__ by Simon Peyton Jones, used with permission to copy, distribute and modify for any purpose with this note included. |
| 181 | +[pemdas]: https://en.wikipedia.org/wiki/Order_of_operations |
| 182 | +[floor]: https://hackage.haskell.org/package/base/docs/Prelude.html#v:floor |
| 183 | +[ceiling]: https://hackage.haskell.org/package/base/docs/Prelude.html#v:ceiling |
0 commit comments