Skip to content

Commit 08ab682

Browse files
committed
Rework number concept
1 parent 594515b commit 08ab682

File tree

14 files changed

+770
-56
lines changed

14 files changed

+770
-56
lines changed

concepts/numbers/about.md

Lines changed: 156 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,183 @@
1-
# Haskell Built-in Numeric Types
1+
# Numbers
22

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].
75

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.
88
`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).
99

10+
Note that when writting negative numbers, you should use parentheses to avoid ambiguity.
11+
12+
```haskell
13+
1
14+
15+
(-1)
16+
```
17+
1018
`Float` corresponds to the set of real numbers, limited by the precision of the computer.
1119
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
1251

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+
```
1455

1556
## Arithmetic operators
1657

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.
1862

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.
2266

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.
2678

2779
```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
3785
```
3886

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.
4289
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).
4592
4693
```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
49116
```
50117

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
52124

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.
59127

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.
62139
63140
```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
66179
```
67180

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

Comments
 (0)