-
Notifications
You must be signed in to change notification settings - Fork 3
/
numbers.clj
348 lines (199 loc) · 7.82 KB
/
numbers.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
;; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;; An Introduction to Clojure for Light Table users
;; Numbers
;; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;; Instructions
;; ============================================================================
;; To begin, open this file on Light Table.
;; To evaluate a form place the cursor in the form and type ctrl-enter.
;; The first eval will take several seconds. Light Table is creating a
;; connection to a REPL. After the first it will be fast.
;; The result of each eval will apear right next to the form. Some forms like
;; the ns declaration return nil. This is ok. Also, sometimes, the result will
;; be cropped. You can click on it to see the full result.
;; You can put the cursor over some function and press ctrl-shift-d to see the
;; documentation of the function. Press ctrl-shift-d again to make it go away.
;; When you find a comment form you need to select the expressions inside and
;; them eval them. Usually they will cause an error.
(ns numbers)
;; In Clojure there are several types of numbers useful in different
;; situations. Here you can see some of this types. Several of them are just
;; java numbers. Let's start with the number you are going to be using the
;; most in Clojure. They are the default Clojure numbers.
;; Default Clojure numbers
;; ============================================================================
;; Integers
;; ============================================================================
;; Integers in clojure are Java Long by default.
;; Long
;; ----------------------------------------------------------------------------
(type 1)
(type 4738724)
;; You can use octal numbers just stating with 0
(type 017)
(str 017)
;; And hexadecimal numbers stating with 0x
(type 0x1F)
(str 0x1F)
;; There is the r notation for bases until 36
(type 36rZ)
(str 36rZ)
(type 2r11)
(str 2r11)
;; You can find what is the minimum and maximum Long.
Long/MIN_VALUE
Long/MAX_VALUE
;; But what if you need a bigger or smaller number?
;; Clojure has `inc` that adds one to a number and `dec` that subtracts one.
(comment
(inc Long/MAX_VALUE)
(dec Long/MIN_VALUE)
)
;; You get an exception: java.lang.ArithmeticException: integer overflow
;; You can coerce other numbers to Long.
(type (long 1N))
;; BigInt
;; ----------------------------------------------------------------------------
;; Clojure offers you a BigInt type that offer arbitrary precision integers.
;; Just add an `N` to the end of the number. Clojure BigInt is not the same as
;; Java BigInteger.
(type 2N)
(str 2N)
;; You can coerce a Long in a BigInt with `bigint`. Notice the `N` in the end
;; of the result.
(bigint Long/MAX_VALUE)
;; Now we can increment that without and error.
(inc (bigint Long/MAX_VALUE))
;; Is a number a integer?
;; ----------------------------------------------------------------------------
;; You can test with `integer?`
(integer? 1)
(integer? 1N)
;; Floats and ratios aren't integers.
(integer? 0.10)
(integer? 4/3)
;; Float
;; ============================================================================
;; Float numbers default to Java Doubles.
;; Double
;; ----------------------------------------------------------------------------
(type 1.5)
;; You can also use scientific notation.
(type 1E10)
(type 3.5E-6)
;; You can coerce to Double using `double`
(double 1)
;; Floats may do unexpected things.
(str 0.999999999999999999)
;; That happens because there are limitations on the precision of Floats and
;; Doubles. They are aproximations. If you need precision you can use the Ratio
;; or BigDecimal type. We'll talk about these two in a moment.
;; Is a number a float?
;; ----------------------------------------------------------------------------
;; You can check if a number is a float with `float?`
(float? 10.2)
;; Integers and ratios are not floats.
(float? 1)
(float? 1/2)
;; Ratio
;; ============================================================================
;; Clojure has a Ratio type to represent rational numbers. They are arbitrarily
;; precise.
(type 3/4)
;; You can coerce to ratio with `rationalize`.
(rationalize 0.5)
;; You can get the numerator of the ratio with `numerator`. And the denominator
;; with `denominator`
(numerator 4/6)
(denominator 4/6)
;; What just happened? Clojure simplifies your ratio it's possible. So `4/6`
;; becomes `2/3`.
(str 4/6)
;; Is a number a ratio?
;; ----------------------------------------------------------------------------
;; You can check if a number is a ratio with `ratio?`
(ratio? 7/5)
;; Integers are not ratios. Even when they look like one.
(ratio? 1)
(ratio? 1N)
(ratio? 10/5)
(ratio? 4712389758912758912074901230/2)
;; `10/5` is not a Ratio and neither is `4712389758912758912074901230/2`. When
;; simplification is possible ratios will be coerced to Long or BigInt.
(type 10/5)
(type 4712389758912758912074901230/2)
;; Floats are not ratios as well
(ratio? 0.5)
;; BigDecimal
;; ============================================================================
;; Clojure has a BigDecimal type to represent rational numbers. It's a Java
;; BigDecimal. To create one, you add a `M` to the end of the number. If you
;; need some calculation to be precise, you should use a BigDecimal or a Ratio.
;; Floats will give you headaches.
(type 13.5M)
(type 1M)
;; You can coerce a number to BigDecimal with `bigdec`.
(bigdec 1/2)
(bigdec 2)
;; You can define the precision and rounding in a BigDecimal math operation
;; with `with-precision`. Here is some examples.
(with-precision 0 (inc 1.3111111M))
(with-precision 1 (inc 1.3111111M))
(with-precision 2 (inc 1.3111111M))
(with-precision 3 (inc 1.3111111M))
(with-precision 2 :rounding UP (inc 1.3111111M))
(with-precision 2 :rounding DOWN (inc 1.3111111M))
;; We will see more about this in the math tutorial.
;; Is a number a BigDecimal?
;; ----------------------------------------------------------------------------
;; You can check if a number is a BigDecimal with `decimal?`
(decimal? 10M)
;; Integers, floats and ratios are not BigDecimal.
(decimal? 1)
(decimal? 0.5)
(decimal? 1/2)
;; Other numbers
;; ============================================================================
;; These number are mainly for interop purposes. Clojure may even convert them
;; to default types without warning. You probably shouldn't use these if you
;; are not sure you need them.
;; Other integers
;; ----------------------------------------------------------------------------
;; We can use `byte`, `short`, `int` and `biginteger` to coerce to those types.
(type (byte 127))
(type (short 10))
(type (int 1))
(type (biginteger 800))
;; There is also the interop option to get instances of these numbers.
(Byte. "70")
(type (Byte. "70"))
(Short. "10")
(type (Short. "10"))
(Integer. 4)
(type (Integer. 4))
(BigInteger. "4")
(type (BigInteger. "4"))
;; Clojure may convert them to default types.
(type (+ (byte 1) (byte 2)))
;; All those types are also considered integers for Clojure.
(integer? (byte 127))
(integer? (short 10))
(integer? (int 1))
(integer? (biginteger 80))
;; Other floats
;; ----------------------------------------------------------------------------
;; Float
;; ----------------------------------------------------------------------------
;; Floats are less precise than Doubles, but you can coerce to Float using
;; `float`.
(type (float 1.5))
;; There is also the interop.
(Float. "10")
;; Clojure may convert them to Double without warning.
(type (+ (float 1.5) (float 1.1)))
;; Floats are also float for Clojure.
(float? (float 1.5))
;; Next
;; ============================================================================
;; In another tutorial we will see math operations, what happens when we
;; use different type of numbers in a operation and how to compare numbers.