functionalscript 0.0.506 → 0.0.507

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dev/module.mjs CHANGED
@@ -79,7 +79,7 @@ const remove_tail = v => dif => v.slice(0, v.length - dif)
79
79
  const self = globalThis
80
80
 
81
81
  /** @type {() => Promise<FsPromises>} */
82
- export const fs = () => import(self.Deno ? 'https://deno.land/std/node/fs/promises.ts' : 'node:fs/promises')
82
+ export const fs = () => import(self.Deno ? 'https://deno.land/std@0.177.0/node/fs/promises.ts' : 'node:fs/promises')
83
83
 
84
84
  /** @type {(code: number) => never} */
85
85
  export const exit = self.Deno ? self.Deno.exit : process.exit
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.0.506",
3
+ "version": "0.0.507",
4
4
  "description": "FunctionalScript is a functional subset of JavaScript",
5
5
  "main": "module.f.cjs",
6
6
  "scripts": {
@@ -1,14 +1,16 @@
1
1
  const compare = require('../function/compare/module.f.cjs')
2
2
  const { abs, sign } = require('../bigint/module.f.cjs')
3
+ const { todo } = require('../../dev/module.f.cjs')
3
4
 
4
5
  /** @typedef {readonly[bigint,number]} BigFloat */
5
6
 
6
- const minSignificand = 0b10_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000n
7
+ const twoPow53 = 0b0010_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000n
8
+ const twoPow54 = 0b0100_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000n
7
9
 
8
10
  /** @type {(value: BigFloat) => (min: bigint) => BigFloat} */
9
- const increaseMantissa = ([m,e]) => min => {
11
+ const increaseMantissa = ([m, e]) => min => {
10
12
  if (m === 0n) {
11
- return [m,e]
13
+ return [m, e]
12
14
  }
13
15
  const s = sign(m)
14
16
  m = abs(m)
@@ -21,11 +23,43 @@ const increaseMantissa = ([m,e]) => min => {
21
23
  }
22
24
  }
23
25
 
26
+ /** @type {(value: BigFloat) => (max: bigint) => BigFloat} */
27
+ const decreaseMantissa = ([m, e]) => max => {
28
+ if (m === 0n) {
29
+ return [m, e]
30
+ }
31
+ const s = sign(m)
32
+ m = abs(m)
33
+ while (true) {
34
+ if (m < max) {
35
+ return [BigInt(s) * m, e]
36
+ }
37
+ m = m >> 1n
38
+ e++
39
+ }
40
+ }
41
+
24
42
  /** @type {(base: bigint) => (exp: number) => bigint} */
25
43
  const pow = base => exp => base ** BigInt(exp)
26
44
 
27
45
  const pow5 = pow(5n)
28
46
 
47
+ /** @type {(div: BigFloat) => (p: bigint) => BigFloat} */
48
+ const divide = ([m, e]) => div => {
49
+ const mabs = abs(m)
50
+ const q = mabs / div
51
+ const s = BigInt(sign(m))
52
+ const [q53, e53] = decreaseMantissa([q, e])(twoPow54)
53
+ const r = q53 & 1n
54
+ const q52 = q53 >> 1n
55
+ const e52 = e53 + 1
56
+ if (r === 1n && mabs === q * div && q === q53 >> BigInt(e - e53)) {
57
+ const odd = q52 & 1n
58
+ return [s * (q52 + odd), e52]
59
+ }
60
+ return [s * (q52 + r), e52]
61
+ }
62
+
29
63
  /** @type {(dec: BigFloat) => BigFloat} */
30
64
  const decToBin = dec => {
31
65
  if (dec[0] === 0n) {
@@ -34,11 +68,11 @@ const decToBin = dec => {
34
68
  if (dec[1] >= 0) {
35
69
  /** @type {BigFloat} */
36
70
  const bin = [dec[0] * pow5(dec[1]), dec[1]]
37
- return increaseMantissa(bin)(minSignificand)
71
+ return divide(increaseMantissa(bin)(twoPow53))(1n)
38
72
  }
39
73
  const p = pow5(-dec[1])
40
- const inc = increaseMantissa(dec)(p * minSignificand)
41
- return [inc[0] / p, inc[1]]
74
+ const [m, e] = increaseMantissa(dec)(p * twoPow53)
75
+ return divide([m, e])(p)
42
76
  }
43
77
 
44
78
  module.exports = {
@@ -4,58 +4,214 @@ module.exports = {
4
4
  decToBin: [
5
5
  () => {
6
6
  const result = decToBin([0n, 0])
7
- if (result[0] !== 0b00_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000n) { throw result[0] }
7
+ if (result[0] !== 0b0_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000n) { throw result[0].toString(2) }
8
8
  if (result[1] !== 0) { throw result[1] }
9
9
  },
10
10
  () => {
11
11
  const result = decToBin([0n, 10])
12
- if (result[0] !== 0b00_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000n) { throw result[0] }
12
+ if (result[0] !== 0b0_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000n) { throw result[0].toString(2) }
13
13
  if (result[1] !== 0) { throw result[1] }
14
14
  },
15
15
  () => {
16
16
  const result = decToBin([0n, -10])
17
- if (result[0] !== 0b00_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000n) { throw result[0] }
17
+ if (result[0] !== 0b0_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000n) { throw result[0].toString(2) }
18
18
  if (result[1] !== 0) { throw result[1] }
19
19
  },
20
20
  () => {
21
21
  const result = decToBin([1n, 0])
22
- if (result[0] !== 0b10_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000n) { throw result[0] }
23
- if (result[1] !== -53) { throw result[1] }
22
+ if (result[0] !== 0b1_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000n) { throw result[0].toString(2) }
23
+ if (result[1] !== -52) { throw result[1] }
24
24
  },
25
25
  () => {
26
26
  const result = decToBin([1n, 1])
27
- if (result[0] !== 0b10_1000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000n) { throw result[0] }
28
- if (result[1] !== -50) { throw result[1] }
27
+ if (result[0] !== 0b1_0100_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000n) { throw result[0].toString(2) }
28
+ if (result[1] !== -49) { throw result[1] }
29
29
  },
30
30
  () => {
31
31
  const result = decToBin([1000n, -2])
32
- if (result[0] !== 0b10_1000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000n) { throw result[0] }
33
- if (result[1] !== -50) { throw result[1] }
32
+ if (result[0] !== 0b1_0100_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000n) { throw result[0].toString(2) }
33
+ if (result[1] !== -49) { throw result[1] }
34
34
  },
35
35
  () => {
36
36
  const result = decToBin([1n, -1])
37
- if (result[0] !== 0b11_0011_0011_0011_0011_0011_0011_0011_0011_0011_0011_0011_0011_0011n) { throw result[0] }
38
- if (result[1] !== -57) { throw result[1] }
37
+ if (result[0] !== 0b1_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1010n) { throw result[0].toString(2) } //+1
38
+ if (result[1] !== -56) { throw result[1] }
39
39
  },
40
40
  () => {
41
41
  const result = decToBin([-1n, 0])
42
- if (result[0] !== -0b10_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000n) { throw result[0] }
43
- if (result[1] !== -53) { throw result[1] }
42
+ if (result[0] !== -0b1_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000n) { throw result[0].toString(2) }
43
+ if (result[1] !== -52) { throw result[1] }
44
44
  },
45
45
  () => {
46
46
  const result = decToBin([-1n, 1])
47
- if (result[0] !== -0b10_1000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000n) { throw result[0] }
48
- if (result[1] !== -50) { throw result[1] }
47
+ if (result[0] !== -0b1_0100_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000n) { throw result[0].toString(2) }
48
+ if (result[1] !== -49) { throw result[1] }
49
49
  },
50
50
  () => {
51
51
  const result = decToBin([-1000n, -2])
52
- if (result[0] !== -0b10_1000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000n) { throw result[0] }
53
- if (result[1] !== -50) { throw result[1] }
52
+ if (result[0] !== -0b1_0100_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000n) { throw result[0].toString(2) }
53
+ if (result[1] !== -49) { throw result[1] }
54
54
  },
55
55
  () => {
56
56
  const result = decToBin([-1n, -1])
57
- if (result[0] !== -0b11_0011_0011_0011_0011_0011_0011_0011_0011_0011_0011_0011_0011_0011n) { throw result[0] }
58
- if (result[1] !== -57) { throw result[1] }
57
+ if (result[0] !== -0b1_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1010n) { throw result[0].toString(2) } //+1
58
+ if (result[1] !== -56) { throw result[1] }
59
+ },
60
+ () => {
61
+ const result = decToBin([0b10_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0001n, 0]) //54bits (...0.1)
62
+ if (result[0] !== 0b1_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000n) { throw result[0].toString(2) }
63
+ if (result[1] !== 1) { throw result[1] }
64
+ },
65
+ () => {
66
+ const result = decToBin([-0b10_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0011n, 0]) //54bits (...1.1)
67
+ if (result[0] !== -0b1_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0010n) { throw result[0].toString(2) }
68
+ if (result[1] !== 1) { throw result[1] }
69
+ },
70
+ () => {
71
+ const result = decToBin([-0b10_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0001n, 0]) //54bits (...0.1)
72
+ if (result[0] !== -0b1_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000n) { throw result[0].toString(2) }
73
+ if (result[1] !== 1) { throw result[1] }
74
+ },
75
+ () => {
76
+ const result = decToBin([-0b10_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0011n, 0]) //54bits (...1.1)
77
+ if (result[0] !== -0b1_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0010n) { throw result[0].toString(2) }
78
+ if (result[1] !== 1) { throw result[1] }
79
+ },
80
+ () => {
81
+ const result = decToBin([0b100_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0001n, 0]) //55bits (...0.01)
82
+ if (result[0] !== 0b1_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000n) { throw result[0].toString(2) }
83
+ if (result[1] !== 2) { throw result[1] }
84
+ },
85
+ () => {
86
+ const result = decToBin([0b100_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0010n, 0]) //55bits (...0.10)
87
+ if (result[0] !== 0b1_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000n) { throw result[0].toString(2) }
88
+ if (result[1] !== 2) { throw result[1] }
89
+ },
90
+ () => {
91
+ const result = decToBin([0b100_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0110n, 0]) //55bits (...1.10)
92
+ if (result[0] !== 0b1_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0010n) { throw result[0].toString(2) }
93
+ if (result[1] !== 2) { throw result[1] }
94
+ },
95
+ () => {
96
+ const result = decToBin([0b100_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0011n, 0]) //55bits (0.11)
97
+ if (result[0] !== 0b1_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0001n) { throw result[0].toString(2) }
98
+ if (result[1] !== 2) { throw result[1] }
99
+ },
100
+ ],
101
+ roundingPositive: [
102
+ () => {
103
+ const result = decToBin([0b100_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0001n, -1])
104
+ // reminder = 0
105
+ // m = 11001100110011001100110011001100110011001100110011001.101
106
+ // rounding up
107
+ if (result[0] !== 0b1_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1010n) { throw result[0].toString(2) }
108
+ if (result[1] !== 2) { throw result[1] }
109
+ },
110
+ () => {
111
+ const result = decToBin([0b100_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0001_0000n, -1])
112
+ // reminder = 0
113
+ // m = 11001100110011001100110011001100110011001100110011010.000
114
+ // rounding down
115
+ if (result[0] !== 0b1_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1010n) { throw result[0].toString(2) }
116
+ if (result[1] !== 2) { throw result[1] }
117
+ },
118
+ () => {
119
+ const result = decToBin([0b100_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0010_0100n, -1])
120
+ // reminder = 0
121
+ // m = 11001100110011001100110011001100110011001100110011010.100
122
+ // rounding down (to even)
123
+ if (result[0] !== 0b1_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1010n) { throw result[0].toString(2) }
124
+ if (result[1] !== 2) { throw result[1] }
125
+ },
126
+ () => {
127
+ const result = decToBin([0b100_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0010_0101n, -1])
128
+ // reminder = 1
129
+ // m = 11001100110011001100110011001100110011001100110011010.100
130
+ // rounding up
131
+ if (result[0] !== 0b1_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1011n) { throw result[0].toString(2) }
132
+ if (result[1] !== 2) { throw result[1] }
133
+ },
134
+ () => {
135
+ const result = decToBin([0b100_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0010_1001n, -1])
136
+ // reminder = 0
137
+ // m = 11001100110011001100110011001100110011001100110011010.101
138
+ // rounding up
139
+ if (result[0] !== 0b1_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1011n) { throw result[0].toString(2) }
140
+ if (result[1] !== 2) { throw result[1] }
141
+ },
142
+ () => {
143
+ const result = decToBin([0b100_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0011_1101n, -1])
144
+ // reminder = 0
145
+ // m = 11001100110011001100110011001100110011001100110011011.001
146
+ // rounding down
147
+ if (result[0] !== 0b1_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1011n) { throw result[0].toString(2) }
148
+ if (result[1] !== 2) { throw result[1] }
149
+ },
150
+ () => {
151
+ const result = decToBin([0b100_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0100_1100n, -1])
152
+ // reminder = 0
153
+ // m = 11001100110011001100110011001100110011001100110011011.100
154
+ // rounding up (to even)
155
+ if (result[0] !== 0b1_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1100n) { throw result[0].toString(2) }
156
+ if (result[1] !== 2) { throw result[1] }
157
+ }
158
+ ],
159
+ roundingNegative: [
160
+ () => {
161
+ const result = decToBin([-0b100_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0001n, -1])
162
+ // reminder = 0
163
+ // m = -11001100110011001100110011001100110011001100110011001.101
164
+ // rounding down
165
+ if (result[0] !== -0b1_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1010n) { throw result[0].toString(2) }
166
+ if (result[1] !== 2) { throw result[1] }
167
+ },
168
+ () => {
169
+ const result = decToBin([-0b100_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0001_0000n, -1])
170
+ // reminder = 0
171
+ // m = -11001100110011001100110011001100110011001100110011010.000
172
+ // rounding up
173
+ if (result[0] !== -0b1_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1010n) { throw result[0].toString(2) }
174
+ if (result[1] !== 2) { throw result[1] }
175
+ },
176
+ () => {
177
+ const result = decToBin([-0b100_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0010_0100n, -1])
178
+ // reminder = 0
179
+ // m = -11001100110011001100110011001100110011001100110011010.100
180
+ // rounding up (to even)
181
+ if (result[0] !== -0b1_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1010n) { throw result[0].toString(2) }
182
+ if (result[1] !== 2) { throw result[1] }
183
+ },
184
+ () => {
185
+ const result = decToBin([-0b100_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0010_0101n, -1])
186
+ // reminder = 1
187
+ // m = -11001100110011001100110011001100110011001100110011010.100
188
+ // rounding down
189
+ if (result[0] !== -0b1_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1011n) { throw result[0].toString(2) }
190
+ if (result[1] !== 2) { throw result[1] }
191
+ },
192
+ () => {
193
+ const result = decToBin([-0b100_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0010_1001n, -1])
194
+ // reminder = 0
195
+ // m = -11001100110011001100110011001100110011001100110011010.101
196
+ // rounding down
197
+ if (result[0] !== -0b1_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1011n) { throw result[0].toString(2) }
198
+ if (result[1] !== 2) { throw result[1] }
199
+ },
200
+ () => {
201
+ const result = decToBin([-0b100_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0011_1101n, -1])
202
+ // reminder = 0
203
+ // m = -11001100110011001100110011001100110011001100110011011.001
204
+ // rounding up
205
+ if (result[0] !== -0b1_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1011n) { throw result[0].toString(2) }
206
+ if (result[1] !== 2) { throw result[1] }
207
+ },
208
+ () => {
209
+ const result = decToBin([-0b100_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0100_1100n, -1])
210
+ // reminder = 0
211
+ // m = -11001100110011001100110011001100110011001100110011011.100
212
+ // rounding down (to even)
213
+ if (result[0] !== -0b1_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1001_1100n) { throw result[0].toString(2) }
214
+ if (result[1] !== 2) { throw result[1] }
59
215
  }
60
216
  ]
61
217
  }