1
|
|
|
import Rat, { floatToRat, parseRat } from './Rat' |
2
|
|
|
|
3
|
|
|
test('New Rat is the expected type', () => { |
4
|
|
|
const a = new Rat() |
5
|
|
|
expect(typeof a).toBe('object') |
6
|
|
|
expect(a.constructor.name).toBe('Rat') |
7
|
|
|
}) |
8
|
|
|
|
9
|
|
|
test('Value of -13 is -13', () => { |
10
|
|
|
const a = new Rat(-13) |
11
|
|
|
expect(+a).toBe(-13) |
12
|
|
|
}) |
13
|
|
|
|
14
|
|
|
test('Text representation of 69/1 is "69"', () => { |
15
|
|
|
const a = new Rat(69, 1) |
16
|
|
|
expect(a.toString()).toBe('69') |
17
|
|
|
}) |
18
|
|
|
|
19
|
|
|
test('Text representation of -222/840 is "-37/140"', () => { |
20
|
|
|
const a = new Rat(-222, 840) |
21
|
|
|
expect(a.toString()).toBe('-37/140') |
22
|
|
|
}) |
23
|
|
|
|
24
|
|
|
test('Profile of 1/2 is as expected', () => { |
25
|
|
|
const a = new Rat(1, 2) |
26
|
|
|
expect(a.profile).toBe( |
27
|
|
|
'Rat: 1/2 (≈0.5)' + |
28
|
|
|
'\n' + |
29
|
|
|
'Mixed: 1/2' + |
30
|
|
|
'\n' + |
31
|
|
|
'Continued: [0; 2]' + |
32
|
|
|
'\n' + |
33
|
|
|
'Factorization: 2^-1' + |
34
|
|
|
'\n' + |
35
|
|
|
'Egyptian: 1/2' + |
36
|
|
|
'\n' + |
37
|
|
|
'Babylonian: 30 * 60^-1' + |
38
|
|
|
'\n' + |
39
|
|
|
'psin(t): 4/5' + |
40
|
|
|
'\n' + |
41
|
|
|
'pcos(t): 3/5' + |
42
|
|
|
'\n' + |
43
|
|
|
'ptan(t): 4/3', |
44
|
|
|
) |
45
|
|
|
}) |
46
|
|
|
|
47
|
|
|
test('Profile of 7/5 is as expected', () => { |
48
|
|
|
const a = new Rat(7, 5) |
49
|
|
|
expect(a.profile).toBe( |
50
|
|
|
'Rat: 7/5 (≈1.4)' + |
51
|
|
|
'\n' + |
52
|
|
|
'Mixed: 1 + 2/5' + |
53
|
|
|
'\n' + |
54
|
|
|
'Continued: [1; 2, 2]' + |
55
|
|
|
'\n' + |
56
|
|
|
'Factorization: 5^-1 * 7' + |
57
|
|
|
'\n' + |
58
|
|
|
'Egyptian: 1 + 1/3 + 1/15' + |
59
|
|
|
'\n' + |
60
|
|
|
'Babylonian: 1 * 60^0 + 23 * 60^-1 + 59 * 60^-2 + 59 * 60^-3 + 59 * 60^-4 + 59 * 60^-5 + 59 * 60^-6 + 59 * 60^-7 + 59 * 60^-8 + 58 * 60^-9 + 48 * 60^-10 + 23 * 60^-11 + 37 * 60^-12 + 11 * 60^-13 + 14 * 60^-14 + 17 * 60^-15 + 40 * 60^-16 + 29 * 60^-17 + 4 * 60^-18 + 13 * 60^-19 + 54 * 60^-21 + 29 * 60^-22 + 31 * 60^-23 + 52 * 60^-24 + 30 * 60^-25' + |
61
|
|
|
'\n' + |
62
|
|
|
'psin(t): 35/37' + |
63
|
|
|
'\n' + |
64
|
|
|
'pcos(t): -12/37' + |
65
|
|
|
'\n' + |
66
|
|
|
'ptan(t): -35/12', |
67
|
|
|
) |
68
|
|
|
}) |
69
|
|
|
|
70
|
|
|
test('Profile of 420/69 is as expected', () => { |
71
|
|
|
const a = new Rat(420, 69) |
72
|
|
|
expect(a.profile).toBe( |
73
|
|
|
'Rat: 140/23 (≈6.086956521739131)' + |
74
|
|
|
'\n' + |
75
|
|
|
'Mixed: 6 + 2/23' + |
76
|
|
|
'\n' + |
77
|
|
|
'Continued: [6; 11, 2]' + |
78
|
|
|
'\n' + |
79
|
|
|
'Factorization: 2^2 * 5 * 7 * 23^-1' + |
80
|
|
|
'\n' + |
81
|
|
|
'Egyptian: 6 + 1/12 + 1/276' + |
82
|
|
|
'\n' + |
83
|
|
|
'Babylonian: 6 * 60^0 + 5 * 60^-1 + 13 * 60^-2 + 2 * 60^-3 + 36 * 60^-4 + 31 * 60^-5 + 18 * 60^-6 + 15 * 60^-7 + 39 * 60^-8 + 11 * 60^-9 + 43 * 60^-10 + 3 * 60^-11 + 50 * 60^-12 + 54 * 60^-13 + 39 * 60^-14 + 28 * 60^-15 + 27 * 60^-16 + 6 * 60^-17 + 56 * 60^-18 + 41 * 60^-19 + 2 * 60^-20 + 15 * 60^-21 + 21 * 60^-22 + 5 * 60^-23 + 37 * 60^-24 + 30 * 60^-25' + |
84
|
|
|
'\n' + |
85
|
|
|
'psin(t): 6440/20129' + |
86
|
|
|
'\n' + |
87
|
|
|
'pcos(t): -19071/20129' + |
88
|
|
|
'\n' + |
89
|
|
|
'ptan(t): -6440/19071', |
90
|
|
|
) |
91
|
|
|
}) |
92
|
|
|
|
93
|
|
|
// @todo too slow |
94
|
|
|
// test('Profile of 355/113 is as expected', () => { |
95
|
|
|
// const a = new Rat(355, 113) |
96
|
|
|
// expect(a.profile).toBe( |
97
|
|
|
// 'Rat: 355/113 (≈3.1415929203539825)' |
98
|
|
|
// + '\n' + 'Mixed: 3 + 16/113' |
99
|
|
|
// + '\n' + 'Continued: [3; 7, 16]' |
100
|
|
|
// + '\n' + 'Factorization: 5 * 71 * 113^-1' |
101
|
|
|
// + '\n' + 'Egyptian: 3 + 1/8 + 1/61 + 1/5014 + 1/27649202 + 1/1911195900442808' |
102
|
|
|
// + '\n' + 'Babylonian: 3 * 60^0 + 8 * 60^-1 + 29 * 60^-2 + 44 * 60^-3 + 4 * 60^-4 + 14 * 60^-5 + 52 * 60^-6 + 2 * 60^-7 + 7 * 60^-8 + 28 * 60^-9 + 14 * 60^-10 + 8 * 60^-11 + 8 * 60^-12 + 24 * 60^-13 + 46 * 60^-14 + 42 * 60^-15 + 33 * 60^-16 + 4 * 60^-17 + 54 * 60^-18 + 49 * 60^-19 + 5 * 60^-20 + 12 * 60^-21 + 53 * 60^-22 + 26 * 60^-23 + 15 * 60^-24' |
103
|
|
|
// + '\n' + 'psin(t): 40115/69397' |
104
|
|
|
// + '\n' + 'pcos(t): -56628/69397' |
105
|
|
|
// + '\n' + 'ptan(t): -40115/56628' |
106
|
|
|
// ) |
107
|
|
|
// }) |
108
|
|
|
|
109
|
|
|
test('Default is zero', () => { |
110
|
|
|
const a = new Rat() |
111
|
|
|
expect(+a).toBe(0) |
112
|
|
|
}) |
113
|
|
|
|
114
|
|
|
test('One is one', () => { |
115
|
|
|
const a = new Rat(1) |
116
|
|
|
expect(+a).toBe(1) |
117
|
|
|
}) |
118
|
|
|
|
119
|
|
|
test('Cloning maintains the value', () => { |
120
|
|
|
const a = new Rat(42, -69) |
121
|
|
|
const b = a.clone() |
122
|
|
|
expect(+a).toBe(+b) |
123
|
|
|
}) |
124
|
|
|
|
125
|
|
|
test('Mutating a clone does not affect the value of the original', () => { |
126
|
|
|
const a = new Rat(42, -69) |
127
|
|
|
const original = +a |
128
|
|
|
const b = a.clone() |
129
|
|
|
b.n = 33n |
130
|
|
|
expect(+a).toBe(original) |
131
|
|
|
}) |
132
|
|
|
|
133
|
|
|
// test('The reciprocol of zero divided by a negative number is negative infinity', () => { |
134
|
|
|
// const a = new Rat(0, -69) |
135
|
|
|
// expect(+a.inv()).toBe(-Infinity) |
136
|
|
|
// }) |
137
|
|
|
|
138
|
|
|
test('A non-zero integer divided by zero is infinity', () => { |
139
|
|
|
const a = new Rat(13, 0) |
140
|
|
|
expect(+a).toBe(Infinity) |
141
|
|
|
}) |
142
|
|
|
|
143
|
|
|
test('Zero divided by zero is not a number', () => { |
144
|
|
|
const a = new Rat(0, 0) |
145
|
|
|
expect(+a).toBe(NaN) |
146
|
|
|
}) |
147
|
|
|
|
148
|
|
|
test('Zero over a positive number is still zero', () => { |
149
|
|
|
const a = new Rat(0, 21) |
150
|
|
|
expect(+a).toBe(0) |
151
|
|
|
}) |
152
|
|
|
|
153
|
|
|
// test('Zero over a negative number is negative zero', () => { |
154
|
|
|
// const a = new Rat(0, -21) |
155
|
|
|
// expect(+a).toBe(-0) |
156
|
|
|
// }) |
157
|
|
|
|
158
|
|
|
test('The denominator of zero divided by a number greater than zero is normalized to one', () => { |
159
|
|
|
const a = new Rat(0, 42) |
160
|
|
|
const b = new Rat(1, 0) |
161
|
|
|
expect(+a.mediant(b)).toBe(1) |
162
|
|
|
}) |
163
|
|
|
|
164
|
|
|
test('Zero plus zero is zero', () => { |
165
|
|
|
const a = new Rat() |
166
|
|
|
const b = new Rat() |
167
|
|
|
expect(+a.add(b)).toBe(0) |
168
|
|
|
}) |
169
|
|
|
|
170
|
|
|
test('One plus one is two', () => { |
171
|
|
|
const a = new Rat(1) |
172
|
|
|
const b = new Rat(1) |
173
|
|
|
expect(+a.add(b)).toBe(2) |
174
|
|
|
}) |
175
|
|
|
|
176
|
|
|
test('5/7 minus 21/2 is -137/14', () => { |
177
|
|
|
const a = new Rat(5, 7) |
178
|
|
|
const b = new Rat(21, 2) |
179
|
|
|
expect(a.sub(b).toString()).toBe('-137/14') |
180
|
|
|
}) |
181
|
|
|
|
182
|
|
|
test('Five times three is fifteen', () => { |
183
|
|
|
const a = new Rat(5) |
184
|
|
|
const b = new Rat(3) |
185
|
|
|
expect(+a.mul(b)).toBe(15) |
186
|
|
|
}) |
187
|
|
|
|
188
|
|
|
test('-2/3 divided by 13/11 is -22/39', () => { |
189
|
|
|
const a = new Rat(-2, 3) |
190
|
|
|
const b = new Rat(13, 11) |
191
|
|
|
expect(+a.div(b)).toBe(-22 / 39) |
192
|
|
|
}) |
193
|
|
|
|
194
|
|
|
test('Mediant of 0/1 and 1/1 is 1/2', () => { |
195
|
|
|
const a = new Rat() |
196
|
|
|
const b = new Rat(1) |
197
|
|
|
expect(+a.mediant(b)).toBe(1 / 2) |
198
|
|
|
}) |
199
|
|
|
|
200
|
|
|
test('-33 to the power of 0 is 1', () => { |
201
|
|
|
const a = new Rat(-11) |
202
|
|
|
const b = new Rat(0) |
203
|
|
|
expect(+a.pow(b)).toBe(1) |
204
|
|
|
}) |
205
|
|
|
|
206
|
|
|
test('8 to the power of 2/3 is 4', () => { |
207
|
|
|
const a = new Rat(8) |
208
|
|
|
const b = new Rat(2, 3) |
209
|
|
|
expect(+a.pow(b)).toBeCloseTo(4) |
210
|
|
|
}) |
211
|
|
|
|
212
|
|
|
test('5 to the power of 2 is 25', () => { |
213
|
|
|
const a = new Rat(5) |
214
|
|
|
const b = new Rat(2) |
215
|
|
|
expect(+a.pow(b)).toBe(25) |
216
|
|
|
}) |
217
|
|
|
|
218
|
|
|
test('Minimum of 3/5 and 5/3 is 5/3', () => { |
219
|
|
|
const a = new Rat(3, 5) |
220
|
|
|
const b = new Rat(5, 3) |
221
|
|
|
expect(+a.min(b)).toBe(3 / 5) |
222
|
|
|
}) |
223
|
|
|
|
224
|
|
|
test('Minimum of -3/5 and -5/3 is -5/3', () => { |
225
|
|
|
const a = new Rat(-3, 5) |
226
|
|
|
const b = new Rat(-5, 3) |
227
|
|
|
expect(+a.min(b)).toBe(-5 / 3) |
228
|
|
|
}) |
229
|
|
|
|
230
|
|
|
test('Maximum of 7/15 and -5/3 is 7/15', () => { |
231
|
|
|
const a = new Rat(7, 15) |
232
|
|
|
const b = new Rat(-5, 3) |
233
|
|
|
expect(+a.max(b)).toBe(7 / 15) |
234
|
|
|
}) |
235
|
|
|
|
236
|
|
|
test('Maximum of -7/15 and 5/3 is 5/3', () => { |
237
|
|
|
const a = new Rat(-7, 15) |
238
|
|
|
const b = new Rat(5, 3) |
239
|
|
|
expect(+a.max(b)).toBe(5 / 3) |
240
|
|
|
}) |
241
|
|
|
|
242
|
|
|
test('Dot product of 3/5 and 7/3 is 36', () => { |
243
|
|
|
const a = new Rat(3, 5) |
244
|
|
|
const b = new Rat(7, 3) |
245
|
|
|
expect(Number(a.dot(b))).toBe(36) |
246
|
|
|
}) |
247
|
|
|
|
248
|
|
|
test('7/3 equals 7/3', () => { |
249
|
|
|
const a = new Rat(7, 3) |
250
|
|
|
const b = new Rat(7, 3) |
251
|
|
|
expect(a.equals(b)).toBe(true) |
252
|
|
|
}) |
253
|
|
|
|
254
|
|
|
test('7/3 does not equal 5/3', () => { |
255
|
|
|
const a = new Rat(7, 3) |
256
|
|
|
const b = new Rat(5, 3) |
257
|
|
|
expect(a.equals(b)).toBe(false) |
258
|
|
|
}) |
259
|
|
|
|
260
|
|
|
test('7/3 approximates 7/3', () => { |
261
|
|
|
const a = new Rat(7, 3) |
262
|
|
|
const b = new Rat(7, 3) |
263
|
|
|
expect(a.approximates(+b)).toBe(true) |
264
|
|
|
}) |
265
|
|
|
|
266
|
|
|
test('7/3 does not approximate 47/3', () => { |
267
|
|
|
const a = new Rat(7, 3) |
268
|
|
|
const b = new Rat(37, 3) |
269
|
|
|
expect(a.approximates(+b)).toBe(false) |
270
|
|
|
}) |
271
|
|
|
|
272
|
|
|
test('1/100000000000000001 approximates 1/100000000000000002', () => { |
273
|
|
|
const a = new Rat(1, 100000000000000001n) |
274
|
|
|
const b = new Rat(1, 100000000000000002n) |
275
|
|
|
expect(a.approximates(+b)).toBe(true) |
276
|
|
|
}) |
277
|
|
|
|
278
|
|
|
test('13/3 is greater than 12/3', () => { |
279
|
|
|
const a = new Rat(13, 3) |
280
|
|
|
const b = new Rat(12, 3) |
281
|
|
|
expect(a.isGreaterThan(b)).toBe(true) |
282
|
|
|
}) |
283
|
|
|
|
284
|
|
|
test('11/3 is less than 12/3', () => { |
285
|
|
|
const a = new Rat(11, 3) |
286
|
|
|
const b = new Rat(12, 3) |
287
|
|
|
expect(a.isLessThan(b)).toBe(true) |
288
|
|
|
}) |
289
|
|
|
|
290
|
|
|
test('Absolute value of -3 is 3', () => { |
291
|
|
|
const a = new Rat(-1) |
292
|
|
|
expect(+a.abs()).toBe(1) |
293
|
|
|
}) |
294
|
|
|
|
295
|
|
|
test('Absolute value of 5 is 5', () => { |
296
|
|
|
const a = new Rat(5) |
297
|
|
|
expect(+a.abs()).toBe(5) |
298
|
|
|
}) |
299
|
|
|
|
300
|
|
|
test('Opposite of -3/2 is 3/2', () => { |
301
|
|
|
const a = new Rat(-3, 2) |
302
|
|
|
expect(+a.neg()).toBe(3 / 2) |
303
|
|
|
}) |
304
|
|
|
|
305
|
|
|
test('6/4 is not negative', () => { |
306
|
|
|
const a = new Rat(6, 4) |
307
|
|
|
expect(a.isNegative()).toBe(false) |
308
|
|
|
}) |
309
|
|
|
|
310
|
|
|
test('-7/4 is negative', () => { |
311
|
|
|
const a = new Rat(-7, 4) |
312
|
|
|
expect(a.isNegative()).toBe(true) |
313
|
|
|
}) |
314
|
|
|
|
315
|
|
|
test('-71/9 is finite', () => { |
316
|
|
|
const a = new Rat(-71, 9) |
317
|
|
|
expect(a.isFinite()).toBe(true) |
318
|
|
|
}) |
319
|
|
|
|
320
|
|
|
test('Infinity is not finite', () => { |
321
|
|
|
const a = floatToRat(Infinity) |
322
|
|
|
expect(a.isFinite()).toBe(false) |
323
|
|
|
}) |
324
|
|
|
|
325
|
|
|
test('Reciprocol of -3/5 is -5/3', () => { |
326
|
|
|
const a = new Rat(-3, 5) |
327
|
|
|
expect(+a.inv()).toBe(-5 / 3) |
328
|
|
|
}) |
329
|
|
|
|
330
|
|
|
test('Square root of one is one', () => { |
331
|
|
|
const a = new Rat(1) |
332
|
|
|
expect(+a.root(2)).toBe(1) |
333
|
|
|
}) |
334
|
|
|
|
335
|
|
|
test('Square root of 256 is 16', () => { |
336
|
|
|
const a = new Rat(256) |
337
|
|
|
expect(+a.sqrt()).toBe(16) |
338
|
|
|
}) |
339
|
|
|
|
340
|
|
|
test('5th root of 759375/16807 is 15/7', () => { |
341
|
|
|
const a = new Rat(759375, 16807) |
342
|
|
|
const n = 5 |
343
|
|
|
expect(+a.root(n)).toBe(15 / 7) |
344
|
|
|
}) |
345
|
|
|
|
346
|
|
|
test('Root of infinity is also infinity', () => { |
347
|
|
|
const a = new Rat(1, 0) |
348
|
|
|
const n = 7 |
349
|
|
|
expect(+a.root(n)).toBe(Infinity) |
350
|
|
|
}) |
351
|
|
|
|
352
|
|
|
test('Root of a negative throws up', () => { |
353
|
|
|
const a = new Rat(-1) |
354
|
|
|
expect(() => { |
355
|
|
|
a.sqrt() |
356
|
|
|
}).toThrow( |
357
|
|
|
'Roots of negative numbers like -1 are too complex for this basic library', |
358
|
|
|
) |
359
|
|
|
}) |
360
|
|
|
|
361
|
|
|
test('4242/666 is rounded to 6', () => { |
362
|
|
|
const a = new Rat(4242, 666) |
363
|
|
|
expect(Number(a.round())).toBe(6) |
364
|
|
|
}) |
365
|
|
|
|
366
|
|
|
test('Flooring 420.69 is 420', () => { |
367
|
|
|
const a = floatToRat(420.69) |
368
|
|
|
expect(a.floor()).toBe(420n) |
369
|
|
|
}) |
370
|
|
|
|
371
|
|
|
test('Flooring -42.69 is -43', () => { |
372
|
|
|
const a = floatToRat(-42.69) |
373
|
|
|
expect(a.floor()).toBe(-43n) |
374
|
|
|
}) |
375
|
|
|
|
376
|
|
|
test('Ceilinging -420.69 is -420', () => { |
377
|
|
|
const a = floatToRat(-420.69) |
378
|
|
|
expect(a.ceil()).toBe(-420n) |
379
|
|
|
}) |
380
|
|
|
|
381
|
|
|
test('psin(0) = 0', () => { |
382
|
|
|
const a = new Rat(0) |
383
|
|
|
expect(+a.psin()).toBe(0) |
384
|
|
|
}) |
385
|
|
|
|
386
|
|
|
test('psin(1) = 1', () => { |
387
|
|
|
const a = new Rat(1) |
388
|
|
|
expect(+a.psin()).toBe(1) |
389
|
|
|
}) |
390
|
|
|
|
391
|
|
|
test('psin(-1) = -1', () => { |
392
|
|
|
const a = new Rat(-1) |
393
|
|
|
expect(+a.psin()).toBe(-1) |
394
|
|
|
}) |
395
|
|
|
|
396
|
|
|
test('psin(Infinity) = 0', () => { |
397
|
|
|
const a = floatToRat(Infinity) |
398
|
|
|
expect(+a.psin()).toBe(0) |
399
|
|
|
}) |
400
|
|
|
|
401
|
|
|
test('psin(1/2) = 4/5', () => { |
402
|
|
|
const a = new Rat(1, 2) |
403
|
|
|
expect(a.psin().toString()).toBe('4/5') |
404
|
|
|
}) |
405
|
|
|
|
406
|
|
|
test('psin(2) = 4/5', () => { |
407
|
|
|
const a = new Rat(2) |
408
|
|
|
expect(a.psin().toString()).toBe('4/5') |
409
|
|
|
}) |
410
|
|
|
|
411
|
|
|
test('psin(3) = 3/5', () => { |
412
|
|
|
const a = new Rat(3) |
413
|
|
|
expect(a.psin().toString()).toBe('3/5') |
414
|
|
|
}) |
415
|
|
|
|
416
|
|
|
test('pcos(0) = 1', () => { |
417
|
|
|
const a = new Rat(0) |
418
|
|
|
expect(+a.pcos()).toBe(1) |
419
|
|
|
}) |
420
|
|
|
|
421
|
|
|
test('pcos(1) = 0', () => { |
422
|
|
|
const a = new Rat(1) |
423
|
|
|
expect(+a.pcos()).toBe(0) |
424
|
|
|
}) |
425
|
|
|
|
426
|
|
|
test('pcos(-1) = 0', () => { |
427
|
|
|
const a = new Rat(-1) |
428
|
|
|
expect(+a.pcos()).toBe(0) |
429
|
|
|
}) |
430
|
|
|
|
431
|
|
|
test('pcos(Infinity) = -1', () => { |
432
|
|
|
const a = floatToRat(Infinity) |
433
|
|
|
expect(+a.pcos()).toBe(-1) |
434
|
|
|
}) |
435
|
|
|
|
436
|
|
|
test('pcos(1/2) = 3/5', () => { |
437
|
|
|
const a = new Rat(1, 2) |
438
|
|
|
expect(a.pcos().toString()).toBe('3/5') |
439
|
|
|
}) |
440
|
|
|
|
441
|
|
|
test('pcos(2) = -3/5', () => { |
442
|
|
|
const a = new Rat(2) |
443
|
|
|
expect(a.pcos().toString()).toBe('-3/5') |
444
|
|
|
}) |
445
|
|
|
|
446
|
|
|
test('pcos(3) = -4/5', () => { |
447
|
|
|
const a = new Rat(3) |
448
|
|
|
expect(a.pcos().toString()).toBe('-4/5') |
449
|
|
|
}) |
450
|
|
|
|
451
|
|
|
test('ptan(0) = 0', () => { |
452
|
|
|
const a = new Rat(0) |
453
|
|
|
expect(+a.ptan()).toBe(0) |
454
|
|
|
}) |
455
|
|
|
|
456
|
|
|
test('ptan(1) = Infinity', () => { |
457
|
|
|
const a = new Rat(1) |
458
|
|
|
expect(+a.ptan()).toBe(Infinity) |
459
|
|
|
}) |
460
|
|
|
|
461
|
|
|
test('ptan(-1) = -1/0', () => { |
462
|
|
|
const a = new Rat(-1) |
463
|
|
|
expect(a.ptan().toString()).toBe('-1/0') |
464
|
|
|
}) |
465
|
|
|
|
466
|
|
|
test('ptan(Infinity) = 0', () => { |
467
|
|
|
const a = floatToRat(Infinity) |
468
|
|
|
expect(+a.ptan()).toBe(0) |
469
|
|
|
}) |
470
|
|
|
|
471
|
|
|
test('Mixed fraction of -33/5 is "-6 + -3/5"', () => { |
472
|
|
|
const a = new Rat(-33, 5) |
473
|
|
|
expect(a.mixedFractionString()).toBe('-6 + -3/5') |
474
|
|
|
}) |
475
|
|
|
|
476
|
|
|
test('Continued fraction of 0 is "[0]"', () => { |
477
|
|
|
const a = new Rat(0) |
478
|
|
|
expect(a.continuedFractionString()).toBe('[0]') |
479
|
|
|
}) |
480
|
|
|
|
481
|
|
|
test('Continued fraction of 1 is "[1]"', () => { |
482
|
|
|
const a = new Rat(1) |
483
|
|
|
expect(a.continuedFractionString()).toBe('[1]') |
484
|
|
|
}) |
485
|
|
|
|
486
|
|
|
test('Continued fraction of Infinity is "[]"', () => { |
487
|
|
|
const a = new Rat(1, 0) |
488
|
|
|
expect(a.continuedFractionString()).toBe('[]') |
489
|
|
|
}) |
490
|
|
|
|
491
|
|
|
test('Continued fraction coefficients of 6/9 are [0, 1, 2]', () => { |
492
|
|
|
const a = new Rat(6, 9) |
493
|
|
|
const ex = [0, 1, 2] |
494
|
|
|
const r = [] |
495
|
|
|
for (const n of a.continuedFraction()) { |
496
|
|
|
r.push(n) |
497
|
|
|
} |
498
|
|
|
expect(r).toStrictEqual(ex) |
499
|
|
|
}) |
500
|
|
|
|
501
|
|
|
test('Continued fraction of 2 is "[2]"', () => { |
502
|
|
|
const a = new Rat(2) |
503
|
|
|
expect(a.continuedFractionString()).toBe('[2]') |
504
|
|
|
}) |
505
|
|
|
|
506
|
|
|
test('Continued fraction of 1/2 is "[0; 2]"', () => { |
507
|
|
|
const a = new Rat(1, 2) |
508
|
|
|
expect(a.continuedFractionString()).toBe('[0; 2]') |
509
|
|
|
}) |
510
|
|
|
|
511
|
|
|
test('Continued fraction of 5/7 is "[0; 1, 2]"', () => { |
512
|
|
|
const a = new Rat(5, 7) |
513
|
|
|
expect(a.continuedFractionString()).toBe('[0; 1, 2, 2]') |
514
|
|
|
}) |
515
|
|
|
|
516
|
|
|
test('Prime factorization of 360 is "2^3 * 3^2 * 5"', () => { |
517
|
|
|
const a = new Rat(360) |
518
|
|
|
expect(a.primeFactorizationString()).toBe('2^3 * 3^2 * 5') |
519
|
|
|
}) |
520
|
|
|
|
521
|
|
|
test('Prime factorization of 36/31 is "2^2 * 3^2 * 31^-1"', () => { |
522
|
|
|
const a = new Rat(36, 31) |
523
|
|
|
expect(a.primeFactorizationString()).toBe('2^2 * 3^2 * 31^-1') |
524
|
|
|
}) |
525
|
|
|
|
526
|
|
|
test('Prime factorization of 53155782/127979960268013673033516151007 is "?"', () => { |
527
|
|
|
const a = new Rat(53155782n, 127979960268013673033516151007n) |
528
|
|
|
expect(a.primeFactorizationString()).toBe( |
529
|
|
|
'2 * 3^2 * 29 * 79 * 433^-1 * 1279^-3 * 1289 * 19387^-4', |
530
|
|
|
) |
531
|
|
|
}) |
532
|
|
|
|
533
|
|
|
test('Prime factorization of 17/360 is "2^-3 * 3^-2 * 5^-1 * 17"', () => { |
534
|
|
|
const a = new Rat(17, 360) |
535
|
|
|
expect(a.primeFactorizationString()).toBe('2^-3 * 3^-2 * 5^-1 * 17') |
536
|
|
|
}) |
537
|
|
|
|
538
|
|
|
test('Egyptian fraction for 5/8 is "1/2 + 1/8"', () => { |
539
|
|
|
const a = new Rat(5, 8) |
540
|
|
|
expect(a.egyptianFractionString()).toBe('1/2 + 1/8') |
541
|
|
|
}) |
542
|
|
|
|
543
|
|
|
test('Egyptian fraction for 17/360 is "1/22 + 1/566 + 1/1120680"', () => { |
544
|
|
|
const a = new Rat(17, 360) |
545
|
|
|
expect(a.egyptianFractionString()).toBe('1/22 + 1/566 + 1/1120680') |
546
|
|
|
}) |
547
|
|
|
|
548
|
|
|
test('Egyptian fraction for -1/12 is "-1 + 1/2 + 1/3 + 1/12"', () => { |
549
|
|
|
const a = new Rat(-1, 12) |
550
|
|
|
expect(a.egyptianFractionString()).toBe('-1 + 1/2 + 1/3 + 1/12') |
551
|
|
|
}) |
552
|
|
|
|
553
|
|
|
test('Egyptian fraction for 4096 is as expected', () => { |
554
|
|
|
const a = new Rat(4096) |
555
|
|
|
expect(a.egyptianFractionString()).toBe('4096') |
556
|
|
|
}) |
557
|
|
|
|
558
|
|
|
test('Babylonian fraction for 1/60 is as expected', () => { |
559
|
|
|
const a = new Rat(1, 60) |
560
|
|
|
expect(a.babylonianFractionString()).toBe('1 * 60^-1') |
561
|
|
|
}) |
562
|
|
|
|
563
|
|
|
test('Babylonian fraction for 2/3 is as expected', () => { |
564
|
|
|
const a = new Rat(2, 3) |
565
|
|
|
expect(a.babylonianFractionString()).toBe('40 * 60^-1') |
566
|
|
|
}) |
567
|
|
|
|
568
|
|
|
test('Babylonian fraction for 666/360 is as expected', () => { |
569
|
|
|
const a = new Rat(666, 360) |
570
|
|
|
expect(a.babylonianFractionString()).toBe('1 * 60^0 + 51 * 60^-1') |
571
|
|
|
}) |
572
|
|
|
|
573
|
|
|
test('Babylonian fraction for 181237/10 is "5 * 60^2 + 2 * 60^1 + 3 * 60^0 + 42 * 60^-1"', () => { |
574
|
|
|
const a = new Rat(181237, 10) |
575
|
|
|
expect(a.babylonianFractionString()).toBe( |
576
|
|
|
'5 * 60^2 + 2 * 60^1 + 3 * 60^0 + 42 * 60^-1', |
577
|
|
|
) |
578
|
|
|
}) |
579
|
|
|
|
580
|
|
|
test('Babylonian fraction for 420 is as expected', () => { |
581
|
|
|
const a = new Rat(420) |
582
|
|
|
expect(a.babylonianFractionString()).toBe('7 * 60^1') |
583
|
|
|
}) |
584
|
|
|
|
585
|
|
|
test('0.5 is converted to "1/2"', () => { |
586
|
|
|
const n = 0.5 |
587
|
|
|
expect(floatToRat(n).toString()).toBe('1/2') |
588
|
|
|
}) |
589
|
|
|
|
590
|
|
|
test('Not a number is converted to "0/0"', () => { |
591
|
|
|
const n = 0 / 0 |
592
|
|
|
expect(floatToRat(n).toString()).toBe('0/0') |
593
|
|
|
}) |
594
|
|
|
|
595
|
|
|
test('Infinity is converted to "1/0"', () => { |
596
|
|
|
const n = Infinity |
597
|
|
|
expect(floatToRat(n).toString()).toBe('1/0') |
598
|
|
|
}) |
599
|
|
|
|
600
|
|
|
test('-Infinity is converted to "-1/0"', () => { |
601
|
|
|
const n = -Infinity |
602
|
|
|
expect(floatToRat(n).toString()).toBe('-1/0') |
603
|
|
|
}) |
604
|
|
|
|
605
|
|
|
test('42069 is converted to "42069"', () => { |
606
|
|
|
const n = 42069 |
607
|
|
|
expect(floatToRat(n).toString()).toBe('42069') |
608
|
|
|
}) |
609
|
|
|
|
610
|
|
|
test('-1/42069 is converted to "-1/42069"', () => { |
611
|
|
|
const n = -1 / 42069 |
612
|
|
|
expect(floatToRat(n).toString()).toBe('-1/42069') |
613
|
|
|
}) |
614
|
|
|
|
615
|
|
|
test('-420/69 converted to a float and back to a Rat is "-140/23"', () => { |
616
|
|
|
const a = new Rat(-420, 69) |
617
|
|
|
expect(floatToRat(+a).toString()).toBe('-140/23') |
618
|
|
|
}) |
619
|
|
|
|
620
|
|
|
test('Not a number is converted to "0/0"', () => { |
621
|
|
|
const n = 'NaN' |
622
|
|
|
expect(parseRat(n).toString()).toBe('0/0') |
623
|
|
|
}) |
624
|
|
|
|
625
|
|
|
test('"Infinity" is converted to "1/0"', () => { |
626
|
|
|
const n = 'Infinity' |
627
|
|
|
expect(parseRat(n).toString()).toBe('1/0') |
628
|
|
|
}) |
629
|
|
|
|
630
|
|
|
test('"-Infinity" is converted to "-1/0"', () => { |
631
|
|
|
const n = '-Infinity' |
632
|
|
|
expect(parseRat(n).toString()).toBe('-1/0') |
633
|
|
|
}) |
634
|
|
|
|
635
|
|
|
test('"420" converted to a Rat is "420"', () => { |
636
|
|
|
const a = '420' |
637
|
|
|
expect(parseRat(a).toString()).toBe('420') |
638
|
|
|
}) |
639
|
|
|
|
640
|
|
|
test('"-420/69" converted to a Rat is "-140/23"', () => { |
641
|
|
|
const a = '-420/69' |
642
|
|
|
expect(parseRat(a).toString()).toBe('-140/23') |
643
|
|
|
}) |
644
|
|
|
|