nomen-lang 0.0.7 → 0.0.8
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/NOMEN_AGENTS.md +235 -0
- package/core/System/Ansi.nm +150 -0
- package/core/System/Array.nm +358 -0
- package/core/System/BigInt.nm +887 -0
- package/core/System/Buffer.nm +526 -0
- package/core/System/Channel.nm +198 -0
- package/core/System/ClassBuffer.nm +229 -0
- package/core/System/Console.nm +211 -0
- package/core/System/Controls/Button.nm +138 -0
- package/core/System/Controls/CheckBox.nm +158 -0
- package/core/System/Controls/Container.nm +1562 -0
- package/core/System/Controls/Control.nm +28 -0
- package/core/System/Controls/Geometry.nm +101 -0
- package/core/System/Controls/Layout.nm +228 -0
- package/core/System/Controls/LayoutParams.nm +50 -0
- package/core/System/Controls/Text.nm +129 -0
- package/core/System/Controls/TextBox.nm +157 -0
- package/core/System/Controls/Window.nm +280 -0
- package/core/System/Disposable.nm +8 -0
- package/core/System/Enumerable.nm +10 -0
- package/core/System/Equatable.nm +10 -0
- package/core/System/Graph.nm +68 -0
- package/core/System/Hashable.nm +13 -0
- package/core/System/Init.nm +21 -0
- package/core/System/LinkedList.nm +64 -0
- package/core/System/List.nm +44 -0
- package/core/System/Map.nm +153 -0
- package/core/System/Math.nm +54 -0
- package/core/System/Mutex.nm +78 -0
- package/core/System/Nursery.nm +27 -0
- package/core/System/Sendable.nm +9 -0
- package/core/System/Set.nm +97 -0
- package/core/System/Stream/Directory.nm +176 -0
- package/core/System/Stream/File.nm +432 -0
- package/core/System/Stream/Http.nm +453 -0
- package/core/System/String.nm +154 -0
- package/core/System/StringBuilder.nm +249 -0
- package/core/System/Stringable.nm +8 -0
- package/core/System/Task.nm +263 -0
- package/core/System/Test.nm +241 -0
- package/core/System/Text/Json.nm +377 -0
- package/core/System/Text/JsonTree.nm +187 -0
- package/core/System/Text/Regex.nm +655 -0
- package/core/System/Time.nm +112 -0
- package/core/System/Tree.nm +70 -0
- package/core/System/Viewable.nm +27 -0
- package/core/System/bool.nm +66 -0
- package/core/System/char.nm +42 -0
- package/core/System/float.nm +43 -0
- package/core/System/int.nm +54 -0
- package/core/System/int64.nm +42 -0
- package/core/System/int8.nm +42 -0
- package/core/System/uint.nm +42 -0
- package/core/System/uint64.nm +42 -0
- package/core/System/uint8.nm +42 -0
- package/core/docs/System/Ansi.md +40 -0
- package/core/docs/System/Array.md +16 -0
- package/core/docs/System/BigInt.md +30 -0
- package/core/docs/System/Buffer.md +31 -0
- package/core/docs/System/Channel.md +10 -0
- package/core/docs/System/ClassBuffer.md +15 -0
- package/core/docs/System/Console.md +13 -0
- package/core/docs/System/Controls/Button.md +12 -0
- package/core/docs/System/Controls/CheckBox.md +15 -0
- package/core/docs/System/Controls/Container.md +82 -0
- package/core/docs/System/Controls/Control.md +5 -0
- package/core/docs/System/Controls/Geometry.md +26 -0
- package/core/docs/System/Controls/Layout.md +37 -0
- package/core/docs/System/Controls/LayoutParams.md +13 -0
- package/core/docs/System/Controls/Text.md +12 -0
- package/core/docs/System/Controls/TextBox.md +13 -0
- package/core/docs/System/Controls/Window.md +20 -0
- package/core/docs/System/Disposable.md +5 -0
- package/core/docs/System/Enumerable.md +5 -0
- package/core/docs/System/Graph.md +17 -0
- package/core/docs/System/Init.md +9 -0
- package/core/docs/System/LinkedList.md +16 -0
- package/core/docs/System/List.md +13 -0
- package/core/docs/System/Map.md +14 -0
- package/core/docs/System/Math.md +11 -0
- package/core/docs/System/Mutex.md +10 -0
- package/core/docs/System/Nursery.md +5 -0
- package/core/docs/System/Sendable.md +5 -0
- package/core/docs/System/Set.md +14 -0
- package/core/docs/System/Stream/Directory.md +12 -0
- package/core/docs/System/Stream/File.md +21 -0
- package/core/docs/System/String.md +14 -0
- package/core/docs/System/StringBuilder.md +12 -0
- package/core/docs/System/Stringable.md +5 -0
- package/core/docs/System/Task.md +15 -0
- package/core/docs/System/Text/Json.md +12 -0
- package/core/docs/System/Text/JsonTree.md +21 -0
- package/core/docs/System/Text/Regex.md +12 -0
- package/core/docs/System/Time.md +11 -0
- package/core/docs/System/Tree.md +18 -0
- package/core/docs/System/Viewable.md +5 -0
- package/core/docs/System/bool.md +9 -0
- package/core/docs/System/char.md +9 -0
- package/core/docs/System/float.md +9 -0
- package/core/docs/System/int.md +10 -0
- package/core/docs/System/int64.md +9 -0
- package/core/docs/System/int8.md +9 -0
- package/core/docs/System/uint.md +9 -0
- package/core/docs/System/uint64.md +9 -0
- package/core/docs/System/uint8.md +9 -0
- package/core/package.jsonc +4 -0
- package/dist/index.mjs +417 -5490
- package/package.json +33 -30
- package/src/args.ts +171 -0
- package/src/index.ts +53 -104
- package/src/init.ts +128 -0
- package/src/test.ts +6 -2
- package/test/fixtures/build/calc.test +0 -0
- package/test/fixtures/build/calc.test.c +0 -969
- package/test/fixtures/build/main.h +0 -170
- package/test/fixtures/calc.test.nm +0 -32
- package/tsconfig.json +0 -21
- package/vite.config.ts +0 -7
|
@@ -0,0 +1,887 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An arbitrary-precision integer
|
|
3
|
+
**/
|
|
4
|
+
pub struct BigInt {
|
|
5
|
+
var sign = 0
|
|
6
|
+
var len = 0
|
|
7
|
+
var digits = Buffer<int>()
|
|
8
|
+
|
|
9
|
+
pub func new = (ref self, int val, out BigInt) {
|
|
10
|
+
self.sign = 1
|
|
11
|
+
var int v = val
|
|
12
|
+
if v < 0 {
|
|
13
|
+
self.sign = -1
|
|
14
|
+
v = 0 - v
|
|
15
|
+
}
|
|
16
|
+
self.digits.grow_int(4)
|
|
17
|
+
self.digits.zero_int(self.digits.cap)
|
|
18
|
+
self.digits.store_int(0, v)
|
|
19
|
+
self.len = 1
|
|
20
|
+
return self
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
inline func get = (self, int i, out uint64) {
|
|
24
|
+
```
|
|
25
|
+
#arch: c
|
|
26
|
+
return ((unsigned long long*)self->digits.data)[i];
|
|
27
|
+
```
|
|
28
|
+
```
|
|
29
|
+
#arch: aarch64
|
|
30
|
+
ldr x0, [x0, #32]
|
|
31
|
+
ldr x0, [x0, x1, lsl #3]
|
|
32
|
+
```
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
inline func set = (ref self, int i, uint64 val) {
|
|
36
|
+
```
|
|
37
|
+
#arch: c
|
|
38
|
+
((unsigned long long*)self->digits.data)[i] = val;
|
|
39
|
+
```
|
|
40
|
+
```
|
|
41
|
+
#arch: aarch64
|
|
42
|
+
ldr x0, [x19, #32]
|
|
43
|
+
str x2, [x0, x1, lsl #3]
|
|
44
|
+
```
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Raw data-pointer accessors. The limb loops below hoist `digits.data`
|
|
48
|
+
// into a local once (before the loop) and index through it via get_at /
|
|
49
|
+
// set_at, so each limb access is a single strided load/store instead of
|
|
50
|
+
// re-reading self->digits.data every iteration. ptr is held in a uint64.
|
|
51
|
+
inline func data_ptr = (self, out uint64) {
|
|
52
|
+
```
|
|
53
|
+
#arch: c
|
|
54
|
+
return (unsigned long long)self->digits.data;
|
|
55
|
+
```
|
|
56
|
+
```
|
|
57
|
+
#arch: aarch64
|
|
58
|
+
ldr x0, [x0, #32]
|
|
59
|
+
```
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
inline func get_at = (self, uint64 ptr, int i, out uint64) {
|
|
63
|
+
```
|
|
64
|
+
#arch: c
|
|
65
|
+
return ((unsigned long long*)ptr)[i];
|
|
66
|
+
```
|
|
67
|
+
```
|
|
68
|
+
#arch: aarch64
|
|
69
|
+
ldr x0, [x1, x2, lsl #3]
|
|
70
|
+
```
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
inline func set_at = (ref self, uint64 ptr, int i, uint64 val) {
|
|
74
|
+
```
|
|
75
|
+
#arch: c
|
|
76
|
+
((unsigned long long*)ptr)[i] = val;
|
|
77
|
+
```
|
|
78
|
+
```
|
|
79
|
+
#arch: aarch64
|
|
80
|
+
str x3, [x1, x2, lsl #3]
|
|
81
|
+
```
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
func ensure = (ref self, int needed) {
|
|
85
|
+
self.digits.grow_int(needed)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
func clear = (ref self, int len) {
|
|
89
|
+
self.digits.zero_int(len)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
func copy_range_from = (ref self, BigInt src, int start, int count) {
|
|
93
|
+
self.ensure(count)
|
|
94
|
+
var i = 0
|
|
95
|
+
while i < count; i += 1 {
|
|
96
|
+
self.set(i, src.get(start + i))
|
|
97
|
+
}
|
|
98
|
+
self.len = count
|
|
99
|
+
while self.len > 1 {
|
|
100
|
+
if self.get(self.len - 1) != 0 {
|
|
101
|
+
break
|
|
102
|
+
}
|
|
103
|
+
self.len = self.len - 1
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
func add_at = (ref self, BigInt other, int shift) {
|
|
108
|
+
self.ensure(other.len + shift + 1)
|
|
109
|
+
var carry = 0
|
|
110
|
+
var i = 0
|
|
111
|
+
while i < other.len || carry != 0; i += 1 {
|
|
112
|
+
var uint64 a_val = 0
|
|
113
|
+
if i + shift < self.len {
|
|
114
|
+
a_val = self.get(i + shift)
|
|
115
|
+
}
|
|
116
|
+
var uint64 b_val = 0
|
|
117
|
+
if i < other.len {
|
|
118
|
+
b_val = other.get(i)
|
|
119
|
+
}
|
|
120
|
+
var uint64 sum = a_val + b_val
|
|
121
|
+
var c1 = 0
|
|
122
|
+
if sum < a_val {
|
|
123
|
+
c1 = 1
|
|
124
|
+
}
|
|
125
|
+
const uint64 sum2 = sum + carry
|
|
126
|
+
var c2 = 0
|
|
127
|
+
if sum2 < sum {
|
|
128
|
+
c2 = 1
|
|
129
|
+
}
|
|
130
|
+
self.set(i + shift, sum2)
|
|
131
|
+
carry = c1 + c2
|
|
132
|
+
}
|
|
133
|
+
if i + shift > self.len {
|
|
134
|
+
self.len = i + shift
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
func sub_at = (ref self, BigInt other, int shift) {
|
|
139
|
+
var borrow = 0
|
|
140
|
+
var i = 0
|
|
141
|
+
while i < other.len; i += 1 {
|
|
142
|
+
const uint64 a_val = self.get(i + shift)
|
|
143
|
+
const uint64 b_val = other.get(i)
|
|
144
|
+
const uint64 diff = a_val - borrow
|
|
145
|
+
var new_borrow = 0
|
|
146
|
+
if diff > a_val {
|
|
147
|
+
new_borrow = 1
|
|
148
|
+
}
|
|
149
|
+
const uint64 diff2 = diff - b_val
|
|
150
|
+
if diff2 > diff {
|
|
151
|
+
borrow = new_borrow + 1
|
|
152
|
+
} else {
|
|
153
|
+
borrow = new_borrow
|
|
154
|
+
}
|
|
155
|
+
self.set(i + shift, diff2)
|
|
156
|
+
}
|
|
157
|
+
while borrow != 0; i += 1 {
|
|
158
|
+
const uint64 a_val = self.get(i + shift)
|
|
159
|
+
const uint64 diff = a_val - borrow
|
|
160
|
+
if diff > a_val {
|
|
161
|
+
borrow = 1
|
|
162
|
+
} else {
|
|
163
|
+
borrow = 0
|
|
164
|
+
}
|
|
165
|
+
self.set(i + shift, diff)
|
|
166
|
+
}
|
|
167
|
+
while self.len > 1 {
|
|
168
|
+
if self.get(self.len - 1) != 0 {
|
|
169
|
+
break
|
|
170
|
+
}
|
|
171
|
+
self.len = self.len - 1
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// (hi:lo) / d with the quotient truncated to 64 bits.
|
|
176
|
+
// Callers guarantee hi <= d (the running remainder is always < divisor,
|
|
177
|
+
// and Knuth-D q_hat estimation has u_hi <= v_top). When hi == d the true
|
|
178
|
+
// quotient is 2^64 + (lo/d), which saturates to UINT64_MAX (== B-1) — the
|
|
179
|
+
// value Knuth-D expects so its correction step brings q_hat back down.
|
|
180
|
+
// When hi < d the quotient fits in 64 bits and is exact.
|
|
181
|
+
//
|
|
182
|
+
// AArch64 has no 128/64 divide instruction, so this calls compiler-rt's
|
|
183
|
+
// ___udivti3 (linked via clang) instead of a 64-iteration bit loop — ~30x
|
|
184
|
+
// faster. The unsigned compare (b.hs) is required: hi/d can have their
|
|
185
|
+
// sign bit set.
|
|
186
|
+
inline func div128 = (self, uint64 hi, uint64 lo, uint64 d, out uint64) {
|
|
187
|
+
```
|
|
188
|
+
#arch: c
|
|
189
|
+
if (hi >= d) return 18446744073709551615ULL;
|
|
190
|
+
unsigned __int128 n = ((unsigned __int128)hi << 64) | lo;
|
|
191
|
+
return (unsigned long long)(n / d);
|
|
192
|
+
```
|
|
193
|
+
```
|
|
194
|
+
#arch: aarch64
|
|
195
|
+
// x0=self(unused) x1=hi x2=lo x3=d -> x0 = quotient
|
|
196
|
+
// ___udivti3(a=x0:x1, b=x2:x3) -> x0:x1 ; we need a=(hi:lo), b=(d:0)
|
|
197
|
+
cmp x1, x3
|
|
198
|
+
b.hs 1f
|
|
199
|
+
mov x0, x2
|
|
200
|
+
mov x2, x3
|
|
201
|
+
mov x3, #0
|
|
202
|
+
str x30, [sp, #-16]!
|
|
203
|
+
bl ___udivti3
|
|
204
|
+
ldr x30, [sp], #16
|
|
205
|
+
b 2f
|
|
206
|
+
1:
|
|
207
|
+
mov x0, #-1
|
|
208
|
+
2:
|
|
209
|
+
```
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
inline func mul_wide_hi = (self, uint64 a, uint64 b, out uint64) {
|
|
213
|
+
```
|
|
214
|
+
#arch: c
|
|
215
|
+
unsigned __int128 product = (unsigned __int128)(unsigned long long)a * (unsigned long long)b;
|
|
216
|
+
return (unsigned long long)(product >> 64);
|
|
217
|
+
```
|
|
218
|
+
```
|
|
219
|
+
#arch: aarch64
|
|
220
|
+
umulh x0, x1, x2
|
|
221
|
+
```
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
pub func cmp = (self, BigInt other, out int) {
|
|
225
|
+
if self.len != other.len {
|
|
226
|
+
if self.len > other.len {
|
|
227
|
+
return 1
|
|
228
|
+
}
|
|
229
|
+
return -1
|
|
230
|
+
}
|
|
231
|
+
const uint64 sp = self.data_ptr()
|
|
232
|
+
const uint64 op = other.data_ptr()
|
|
233
|
+
var int i = self.len - 1
|
|
234
|
+
while i >= 0; i -= 1 {
|
|
235
|
+
var uint64 a = self.get_at(sp, i)
|
|
236
|
+
var uint64 b = other.get_at(op, i)
|
|
237
|
+
if a != b {
|
|
238
|
+
if a > b {
|
|
239
|
+
return 1
|
|
240
|
+
}
|
|
241
|
+
return -1
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return 0
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
pub func add_to = (ref self, BigInt a, BigInt b) {
|
|
248
|
+
if a.len == 1 && b.len == 1 {
|
|
249
|
+
var uint64 a_val = a.get(0)
|
|
250
|
+
var uint64 b_val = b.get(0)
|
|
251
|
+
const uint64 sum = a_val + b_val
|
|
252
|
+
var carry = 0
|
|
253
|
+
if sum < a_val {
|
|
254
|
+
carry = 1
|
|
255
|
+
}
|
|
256
|
+
self.ensure(2)
|
|
257
|
+
self.set(0, sum)
|
|
258
|
+
self.set(1, carry)
|
|
259
|
+
self.len = 1 + carry
|
|
260
|
+
return
|
|
261
|
+
}
|
|
262
|
+
const int a_len = a.len
|
|
263
|
+
const int b_len = b.len
|
|
264
|
+
var int max_len = a_len
|
|
265
|
+
if b_len > max_len {
|
|
266
|
+
max_len = b_len
|
|
267
|
+
}
|
|
268
|
+
self.ensure(max_len + 2)
|
|
269
|
+
const uint64 ap = a.data_ptr()
|
|
270
|
+
const uint64 bp = b.data_ptr()
|
|
271
|
+
const uint64 sp = self.data_ptr()
|
|
272
|
+
var carry = 0
|
|
273
|
+
var i = 0
|
|
274
|
+
var last_nonzero = 1
|
|
275
|
+
while i < max_len || carry != 0; i += 1 {
|
|
276
|
+
var uint64 a_val = 0
|
|
277
|
+
if i < a_len {
|
|
278
|
+
a_val = a.get_at(ap, i)
|
|
279
|
+
}
|
|
280
|
+
var uint64 b_val = 0
|
|
281
|
+
if i < b_len {
|
|
282
|
+
b_val = b.get_at(bp, i)
|
|
283
|
+
}
|
|
284
|
+
const uint64 sum = a_val + b_val
|
|
285
|
+
var c1 = 0
|
|
286
|
+
if sum < a_val {
|
|
287
|
+
c1 = 1
|
|
288
|
+
}
|
|
289
|
+
const uint64 sum2 = sum + carry
|
|
290
|
+
var c2 = 0
|
|
291
|
+
if sum2 < sum {
|
|
292
|
+
c2 = 1
|
|
293
|
+
}
|
|
294
|
+
self.set_at(sp, i, sum2)
|
|
295
|
+
if sum2 != 0 {
|
|
296
|
+
last_nonzero = i + 1
|
|
297
|
+
}
|
|
298
|
+
carry = c1 + c2
|
|
299
|
+
}
|
|
300
|
+
self.len = i
|
|
301
|
+
if last_nonzero < self.len {
|
|
302
|
+
self.len = last_nonzero
|
|
303
|
+
}
|
|
304
|
+
if self.len == 0 {
|
|
305
|
+
self.len = 1
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
pub func sub_to = (ref self, BigInt a, BigInt b) {
|
|
310
|
+
if a.len == 1 && b.len == 1 {
|
|
311
|
+
self.ensure(1)
|
|
312
|
+
self.set(0, a.get(0) - b.get(0))
|
|
313
|
+
self.len = 1
|
|
314
|
+
return
|
|
315
|
+
}
|
|
316
|
+
self.ensure(a.len)
|
|
317
|
+
const uint64 ap = a.data_ptr()
|
|
318
|
+
const uint64 bp = b.data_ptr()
|
|
319
|
+
const uint64 sp = self.data_ptr()
|
|
320
|
+
var borrow = 0
|
|
321
|
+
var i = 0
|
|
322
|
+
var last_nonzero = 1
|
|
323
|
+
while i < a.len; i += 1 {
|
|
324
|
+
const uint64 a_val = a.get_at(ap, i)
|
|
325
|
+
var uint64 b_val = 0
|
|
326
|
+
if i < b.len {
|
|
327
|
+
b_val = b.get_at(bp, i)
|
|
328
|
+
}
|
|
329
|
+
const uint64 diff = a_val - borrow
|
|
330
|
+
var new_borrow = 0
|
|
331
|
+
if diff > a_val {
|
|
332
|
+
new_borrow = 1
|
|
333
|
+
}
|
|
334
|
+
const uint64 diff2 = diff - b_val
|
|
335
|
+
if diff2 > diff {
|
|
336
|
+
borrow = new_borrow + 1
|
|
337
|
+
} else {
|
|
338
|
+
borrow = new_borrow
|
|
339
|
+
}
|
|
340
|
+
self.set_at(sp, i, diff2)
|
|
341
|
+
if diff2 != 0 {
|
|
342
|
+
last_nonzero = i + 1
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
self.len = a.len
|
|
346
|
+
if last_nonzero < self.len {
|
|
347
|
+
self.len = last_nonzero
|
|
348
|
+
}
|
|
349
|
+
if self.len == 0 {
|
|
350
|
+
self.len = 1
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
pub func mul_to = (ref self, BigInt a, BigInt b, ref BigInt scratch) {
|
|
355
|
+
if a.len == 1 || b.len == 1 {
|
|
356
|
+
var uint64 sv
|
|
357
|
+
var int other_len
|
|
358
|
+
if a.len == 1 {
|
|
359
|
+
sv = a.get(0)
|
|
360
|
+
other_len = b.len
|
|
361
|
+
} else {
|
|
362
|
+
sv = b.get(0)
|
|
363
|
+
other_len = a.len
|
|
364
|
+
}
|
|
365
|
+
self.ensure(other_len + 1)
|
|
366
|
+
const uint64 sp = self.data_ptr()
|
|
367
|
+
var uint64 carry = 0
|
|
368
|
+
var i = 0
|
|
369
|
+
var last_nonzero = 0
|
|
370
|
+
if a.len == 1 {
|
|
371
|
+
const uint64 bp = b.data_ptr()
|
|
372
|
+
while i < other_len || carry != 0; i += 1 {
|
|
373
|
+
var uint64 ov = 0
|
|
374
|
+
if i < other_len {
|
|
375
|
+
ov = b.get_at(bp, i)
|
|
376
|
+
}
|
|
377
|
+
const uint64 lo_prod = sv * ov
|
|
378
|
+
const uint64 hi_prod = self.mul_wide_hi(sv, ov)
|
|
379
|
+
const uint64 result = lo_prod + carry
|
|
380
|
+
var c1 = 0
|
|
381
|
+
if result < lo_prod {
|
|
382
|
+
c1 = 1
|
|
383
|
+
}
|
|
384
|
+
carry = hi_prod + c1
|
|
385
|
+
self.set_at(sp, i, result)
|
|
386
|
+
if result != 0 {
|
|
387
|
+
last_nonzero = i + 1
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
} else {
|
|
391
|
+
var uint64 ap = a.data_ptr()
|
|
392
|
+
while i < other_len || carry != 0; i += 1 {
|
|
393
|
+
var uint64 ov = 0
|
|
394
|
+
if i < other_len {
|
|
395
|
+
ov = a.get_at(ap, i)
|
|
396
|
+
}
|
|
397
|
+
const uint64 lo_prod = sv * ov
|
|
398
|
+
const uint64 hi_prod = self.mul_wide_hi(sv, ov)
|
|
399
|
+
const uint64 result = lo_prod + carry
|
|
400
|
+
var c1 = 0
|
|
401
|
+
if result < lo_prod {
|
|
402
|
+
c1 = 1
|
|
403
|
+
}
|
|
404
|
+
carry = hi_prod + c1
|
|
405
|
+
self.set_at(sp, i, result)
|
|
406
|
+
if result != 0 {
|
|
407
|
+
last_nonzero = i + 1
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
self.len = i
|
|
412
|
+
if last_nonzero < self.len {
|
|
413
|
+
self.len = last_nonzero
|
|
414
|
+
}
|
|
415
|
+
if self.len == 0 {
|
|
416
|
+
self.len = 1
|
|
417
|
+
}
|
|
418
|
+
return
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// Multi-limb × multi-limb: Karatsuba for large operands, schoolbook for small
|
|
422
|
+
const int new_len = a.len + b.len
|
|
423
|
+
if a.len < 32 && b.len < 32 {
|
|
424
|
+
// Schoolbook for small operands
|
|
425
|
+
scratch.ensure(new_len)
|
|
426
|
+
scratch.clear(new_len)
|
|
427
|
+
scratch.len = new_len
|
|
428
|
+
const uint64 ap = a.data_ptr()
|
|
429
|
+
const uint64 bp = b.data_ptr()
|
|
430
|
+
const uint64 scratchp = scratch.data_ptr()
|
|
431
|
+
var i = 0
|
|
432
|
+
while i < a.len; i += 1 {
|
|
433
|
+
const uint64 ai = a.get_at(ap, i)
|
|
434
|
+
var uint64 carry = 0
|
|
435
|
+
var j = 0
|
|
436
|
+
while j < b.len || carry != 0; j += 1 {
|
|
437
|
+
var uint64 bj = 0
|
|
438
|
+
if j < b.len {
|
|
439
|
+
bj = b.get_at(bp, j)
|
|
440
|
+
}
|
|
441
|
+
const uint64 old = scratch.get_at(scratchp, j + i)
|
|
442
|
+
const uint64 lo_prod = ai * bj
|
|
443
|
+
const uint64 hi_prod = scratch.mul_wide_hi(ai, bj)
|
|
444
|
+
const uint64 cur = old + carry
|
|
445
|
+
var c1 = 0
|
|
446
|
+
if cur < old {
|
|
447
|
+
c1 = 1
|
|
448
|
+
}
|
|
449
|
+
const uint64 cur2 = cur + lo_prod
|
|
450
|
+
var c2 = 0
|
|
451
|
+
if cur2 < cur {
|
|
452
|
+
c2 = 1
|
|
453
|
+
}
|
|
454
|
+
carry = c1 + c2 + hi_prod as int
|
|
455
|
+
scratch.set_at(scratchp, j + i, cur2)
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
self.ensure(new_len)
|
|
459
|
+
const uint64 sp = self.data_ptr()
|
|
460
|
+
var last_nonzero = 1
|
|
461
|
+
var k = 0
|
|
462
|
+
while k < new_len; k += 1 {
|
|
463
|
+
const uint64 val = scratch.get_at(scratchp, k)
|
|
464
|
+
self.set_at(sp, k, val)
|
|
465
|
+
if val != 0 {
|
|
466
|
+
last_nonzero = k + 1
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
self.len = last_nonzero
|
|
470
|
+
return
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// Karatsuba: split a = a1*B^m + a0, b = b1*B^m + b0
|
|
474
|
+
// result = z2*B^(2m) + z1*B^m + z0
|
|
475
|
+
// z0 = a0*b0, z2 = a1*b1, z1 = (a0+a1)*(b0+b1) - z0 - z2
|
|
476
|
+
var int m = a.len
|
|
477
|
+
if b.len > m {
|
|
478
|
+
m = b.len
|
|
479
|
+
}
|
|
480
|
+
m = m / 2
|
|
481
|
+
|
|
482
|
+
var int a0_len = m
|
|
483
|
+
if a0_len > a.len {
|
|
484
|
+
a0_len = a.len
|
|
485
|
+
}
|
|
486
|
+
var int b0_len = m
|
|
487
|
+
if b0_len > b.len {
|
|
488
|
+
b0_len = b.len
|
|
489
|
+
}
|
|
490
|
+
const int a1_len = a.len - a0_len
|
|
491
|
+
const int b1_len = b.len - b0_len
|
|
492
|
+
|
|
493
|
+
var a0 = BigInt()
|
|
494
|
+
var a1 = BigInt()
|
|
495
|
+
var b0 = BigInt()
|
|
496
|
+
var b1 = BigInt()
|
|
497
|
+
a0.copy_range_from(a, 0, a0_len)
|
|
498
|
+
b0.copy_range_from(b, 0, b0_len)
|
|
499
|
+
if a1_len > 0 {
|
|
500
|
+
a1.copy_range_from(a, m, a1_len)
|
|
501
|
+
}
|
|
502
|
+
if b1_len > 0 {
|
|
503
|
+
b1.copy_range_from(b, m, b1_len)
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// z0 = a0 * b0
|
|
507
|
+
var z0 = BigInt()
|
|
508
|
+
var s0 = BigInt()
|
|
509
|
+
z0.mul_to(a0, b0, ref s0)
|
|
510
|
+
|
|
511
|
+
// z2 = a1 * b1 (only if both have high parts)
|
|
512
|
+
var z2 = BigInt()
|
|
513
|
+
var s2 = BigInt()
|
|
514
|
+
if a1_len > 0 && b1_len > 0 {
|
|
515
|
+
z2.mul_to(a1, b1, ref s2)
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
// z1 = (a0+a1)*(b0+b1) - z0 - z2
|
|
519
|
+
var aa = BigInt()
|
|
520
|
+
var bb = BigInt()
|
|
521
|
+
var z1 = BigInt()
|
|
522
|
+
var s1 = BigInt()
|
|
523
|
+
aa.add_to(a0, a1)
|
|
524
|
+
bb.add_to(b0, b1)
|
|
525
|
+
z1.mul_to(aa, bb, ref s1)
|
|
526
|
+
z1.sub_at(z0, 0)
|
|
527
|
+
z1.sub_at(z2, 0)
|
|
528
|
+
|
|
529
|
+
// Combine: self = z0 + z1 << m + z2 << (2*m)
|
|
530
|
+
self.ensure(new_len)
|
|
531
|
+
self.clear(new_len)
|
|
532
|
+
self.len = new_len
|
|
533
|
+
self.add_at(z0, 0)
|
|
534
|
+
self.add_at(z1, m)
|
|
535
|
+
self.add_at(z2, m + m)
|
|
536
|
+
while self.len > 1 {
|
|
537
|
+
if self.get(self.len - 1) != 0 {
|
|
538
|
+
break
|
|
539
|
+
}
|
|
540
|
+
self.len = self.len - 1
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
a0.digits.destroy()
|
|
544
|
+
a1.digits.destroy()
|
|
545
|
+
b0.digits.destroy()
|
|
546
|
+
b1.digits.destroy()
|
|
547
|
+
z0.digits.destroy()
|
|
548
|
+
z2.digits.destroy()
|
|
549
|
+
aa.digits.destroy()
|
|
550
|
+
bb.digits.destroy()
|
|
551
|
+
z1.digits.destroy()
|
|
552
|
+
s0.digits.destroy()
|
|
553
|
+
s1.digits.destroy()
|
|
554
|
+
s2.digits.destroy()
|
|
555
|
+
}
|
|
556
|
+
// self = quotient, a = dividend, b = divisor, remainder = remainder
|
|
557
|
+
// Uses remainder's internal buffer as working space
|
|
558
|
+
pub func div_to = (ref self, BigInt a, BigInt b, ref BigInt remainder) {
|
|
559
|
+
if b.len == 1 {
|
|
560
|
+
const uint64 divisor = b.get(0)
|
|
561
|
+
self.ensure(a.len)
|
|
562
|
+
self.len = a.len
|
|
563
|
+
var uint64 rem = 0
|
|
564
|
+
var last_nonzero = 0
|
|
565
|
+
var int i = a.len - 1
|
|
566
|
+
while i >= 0; i -= 1 {
|
|
567
|
+
var uint64 ai = a.get(i)
|
|
568
|
+
const uint64 q_val = self.div128(rem, ai, divisor)
|
|
569
|
+
const uint64 d_lo = divisor & 4294967295
|
|
570
|
+
const uint64 d_hi = divisor >> 32
|
|
571
|
+
const uint64 q_lo = q_val & 4294967295
|
|
572
|
+
const uint64 q_hi = q_val >> 32
|
|
573
|
+
const uint64 p_ll = q_lo * d_lo
|
|
574
|
+
const uint64 p_lh = q_lo * d_hi
|
|
575
|
+
const uint64 p_hl = q_hi * d_lo
|
|
576
|
+
//const uint64 p_hh = q_hi * d_hi
|
|
577
|
+
const uint64 p_mid = p_lh + p_hl
|
|
578
|
+
var p_mc = 0
|
|
579
|
+
if p_mid < p_lh {
|
|
580
|
+
p_mc = 1
|
|
581
|
+
}
|
|
582
|
+
const uint64 p_lo_val = p_ll + (p_mid << 32)
|
|
583
|
+
var p_lo_c = 0
|
|
584
|
+
if p_lo_val < p_ll {
|
|
585
|
+
p_lo_c = 1
|
|
586
|
+
}
|
|
587
|
+
//const uint64 p_hi_val = p_hh + (p_mid >> 32) + (p_mc as uint64 * 4294967296) + p_lo_c as uint64
|
|
588
|
+
const uint64 sub_lo = ai - p_lo_val
|
|
589
|
+
rem = sub_lo
|
|
590
|
+
self.set(i, q_val)
|
|
591
|
+
if q_val != 0 && last_nonzero == 0 {
|
|
592
|
+
last_nonzero = i + 1
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
if last_nonzero == 0 {
|
|
596
|
+
last_nonzero = 1
|
|
597
|
+
}
|
|
598
|
+
if last_nonzero < self.len {
|
|
599
|
+
self.len = last_nonzero
|
|
600
|
+
}
|
|
601
|
+
if self.len == 0 {
|
|
602
|
+
self.len = 1
|
|
603
|
+
}
|
|
604
|
+
remainder.len = 1
|
|
605
|
+
remainder.ensure(1)
|
|
606
|
+
remainder.set(0, rem)
|
|
607
|
+
return
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
// --- Knuth's Algorithm D for multi-limb division ---
|
|
611
|
+
// Uses remainder's digits buffer as working space:
|
|
612
|
+
// [0..n-1] = working divisor (normalized b)
|
|
613
|
+
// [n..n+a.len+1] = working dividend (normalized a)
|
|
614
|
+
const int n = b.len
|
|
615
|
+
const int m = a.len - n
|
|
616
|
+
if m < 0 {
|
|
617
|
+
self.ensure(1)
|
|
618
|
+
self.set(0, 0)
|
|
619
|
+
self.len = 1
|
|
620
|
+
remainder.ensure(a.len)
|
|
621
|
+
remainder.clear(remainder.digits.cap)
|
|
622
|
+
var ci = 0
|
|
623
|
+
while ci < a.len; ci += 1 {
|
|
624
|
+
remainder.set(ci, a.get(ci))
|
|
625
|
+
}
|
|
626
|
+
remainder.len = a.len
|
|
627
|
+
return
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
// D1. Normalize
|
|
631
|
+
const uint64 v_top = b.get(n - 1)
|
|
632
|
+
var shift = 0
|
|
633
|
+
var uint64 clz_mask = 9223372036854775808
|
|
634
|
+
while (clz_mask & v_top) == 0 {
|
|
635
|
+
shift += 1
|
|
636
|
+
clz_mask = clz_mask >> 1
|
|
637
|
+
if shift >= 64 {
|
|
638
|
+
break
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
// Ensure remainder buffer is big enough for working divisor + working dividend
|
|
643
|
+
const int working_size = 2 * n + a.len + 3
|
|
644
|
+
remainder.ensure(working_size)
|
|
645
|
+
remainder.clear(working_size)
|
|
646
|
+
const int wd_off = n
|
|
647
|
+
|
|
648
|
+
// Shift b left by shift into remainder[0..n-1]
|
|
649
|
+
var uint64 carry = 0
|
|
650
|
+
var si = 0
|
|
651
|
+
while si < n; si += 1 {
|
|
652
|
+
const uint64 b_val = b.get(si)
|
|
653
|
+
const uint64 shifted = (b_val << shift) | carry
|
|
654
|
+
remainder.digits.store_int(si, shifted as int)
|
|
655
|
+
if shift > 0 {
|
|
656
|
+
carry = b_val >> (64 - shift)
|
|
657
|
+
} else {
|
|
658
|
+
carry = 0
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
// Shift a left by shift into remainder[wd_off..wd_off+a.len]
|
|
663
|
+
carry = 0
|
|
664
|
+
si = 0
|
|
665
|
+
while si < a.len; si += 1 {
|
|
666
|
+
const uint64 a_val = a.get(si)
|
|
667
|
+
const uint64 shifted = (a_val << shift) | carry
|
|
668
|
+
remainder.digits.store_int(wd_off + si, shifted as int)
|
|
669
|
+
if shift > 0 {
|
|
670
|
+
carry = a_val >> (64 - shift)
|
|
671
|
+
} else {
|
|
672
|
+
carry = 0
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
remainder.digits.store_int(wd_off + si, carry as int)
|
|
676
|
+
const int u_len = a.len + 1
|
|
677
|
+
|
|
678
|
+
// D2. Main loop: for j = m down to 0
|
|
679
|
+
self.ensure(m + 2)
|
|
680
|
+
var int j = m
|
|
681
|
+
while j >= 0; j -= 1 {
|
|
682
|
+
// D3. Calculate q_hat
|
|
683
|
+
const uint64 u_hi = remainder.digits.load_int(wd_off + j + n) as uint64
|
|
684
|
+
const uint64 u_lo = remainder.digits.load_int(wd_off + j + n - 1) as uint64
|
|
685
|
+
const uint64 v_n1 = remainder.digits.load_int(n - 1) as uint64
|
|
686
|
+
|
|
687
|
+
var uint64 q_hat = self.div128(u_hi, u_lo, v_n1)
|
|
688
|
+
|
|
689
|
+
// q_hat correction: try q_hat, decrement if too large
|
|
690
|
+
if n >= 2 {
|
|
691
|
+
var try_count = 0
|
|
692
|
+
while try_count < 3 {
|
|
693
|
+
// compute q_hat * v and compare with u[j+n..j]
|
|
694
|
+
var uint64 hv_carry = 0
|
|
695
|
+
var pi = 0
|
|
696
|
+
while pi < n; pi += 1 {
|
|
697
|
+
const uint64 vv = remainder.digits.load_int(pi) as uint64
|
|
698
|
+
const uint64 lo_prod = q_hat * vv
|
|
699
|
+
const uint64 hi_prod = self.mul_wide_hi(q_hat, vv)
|
|
700
|
+
const uint64 p_lo = lo_prod + hv_carry
|
|
701
|
+
hv_carry = hi_prod
|
|
702
|
+
if p_lo < lo_prod {
|
|
703
|
+
hv_carry += 1
|
|
704
|
+
}
|
|
705
|
+
remainder.digits.store_int(wd_off + u_len + 1 + pi, p_lo as int)
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
// Compare hv_carry with u[j+n]
|
|
709
|
+
const uint64 u_at_jn = remainder.digits.load_int(wd_off + j + n) as uint64
|
|
710
|
+
if hv_carry > u_at_jn {
|
|
711
|
+
q_hat -= 1
|
|
712
|
+
try_count += 1
|
|
713
|
+
continue
|
|
714
|
+
}
|
|
715
|
+
if hv_carry < u_at_jn {
|
|
716
|
+
break
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
// hv_carry == u_at_jn, compare lower limbs
|
|
720
|
+
var int cmp_i = n - 1
|
|
721
|
+
var q_too_big = 0
|
|
722
|
+
while cmp_i >= 0 {
|
|
723
|
+
const uint64 prod_limb = remainder.digits.load_int(wd_off + u_len + 1 + cmp_i) as uint64
|
|
724
|
+
const uint64 u_limb = remainder.digits.load_int(wd_off + j + cmp_i) as uint64
|
|
725
|
+
if prod_limb > u_limb {
|
|
726
|
+
q_too_big = 1
|
|
727
|
+
break
|
|
728
|
+
}
|
|
729
|
+
if prod_limb < u_limb {
|
|
730
|
+
break
|
|
731
|
+
}
|
|
732
|
+
cmp_i -= 1
|
|
733
|
+
}
|
|
734
|
+
if q_too_big != 0 {
|
|
735
|
+
q_hat -= 1
|
|
736
|
+
try_count += 1
|
|
737
|
+
continue
|
|
738
|
+
}
|
|
739
|
+
break
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
// D4. Multiply and subtract: u[j+n..j] -= q_hat * v
|
|
744
|
+
// Step 1: Compute q_hat * v into scratch[0..n]
|
|
745
|
+
var uint64 mul_carry = 0
|
|
746
|
+
var mi = 0
|
|
747
|
+
while mi < n; mi += 1 {
|
|
748
|
+
const uint64 vv = remainder.digits.load_int(mi) as uint64
|
|
749
|
+
const uint64 lo_prod = q_hat * vv
|
|
750
|
+
const uint64 hi_prod = self.mul_wide_hi(q_hat, vv)
|
|
751
|
+
const uint64 prod = lo_prod + mul_carry
|
|
752
|
+
mul_carry = hi_prod
|
|
753
|
+
if prod < lo_prod {
|
|
754
|
+
mul_carry += 1
|
|
755
|
+
}
|
|
756
|
+
remainder.digits.store_int(wd_off + u_len + 1 + mi, prod as int)
|
|
757
|
+
}
|
|
758
|
+
remainder.digits.store_int(wd_off + u_len + 1 + n, mul_carry as int)
|
|
759
|
+
|
|
760
|
+
// Step 2: Subtract prod[0..n] from u[j..j+n]
|
|
761
|
+
var uint64 sub_borrow = 0
|
|
762
|
+
var si2 = 0
|
|
763
|
+
while si2 <= n; si2 += 1 {
|
|
764
|
+
const uint64 u_val = remainder.digits.load_int(wd_off + j + si2) as uint64
|
|
765
|
+
const uint64 p_val = remainder.digits.load_int(wd_off + u_len + 1 + si2) as uint64
|
|
766
|
+
const uint64 diff = u_val - p_val
|
|
767
|
+
var borrow1 = 0
|
|
768
|
+
if diff > u_val {
|
|
769
|
+
borrow1 = 1
|
|
770
|
+
}
|
|
771
|
+
const uint64 diff2 = diff - sub_borrow
|
|
772
|
+
var borrow2 = 0
|
|
773
|
+
if diff2 > diff {
|
|
774
|
+
borrow2 = 1
|
|
775
|
+
}
|
|
776
|
+
sub_borrow = (borrow1 + borrow2) as uint64
|
|
777
|
+
remainder.digits.store_int(wd_off + j + si2, diff2 as int)
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
// D5. Test remainder - if borrow was nonzero (negative result), add back
|
|
781
|
+
if sub_borrow != 0 {
|
|
782
|
+
q_hat -= 1
|
|
783
|
+
var uint64 add_carry = 0
|
|
784
|
+
var ai = 0
|
|
785
|
+
while ai < n; ai += 1 {
|
|
786
|
+
const uint64 v_add = remainder.digits.load_int(ai) as uint64
|
|
787
|
+
const uint64 u_add = remainder.digits.load_int(wd_off + j + ai) as uint64
|
|
788
|
+
const uint64 sum = u_add + v_add + add_carry
|
|
789
|
+
var new_carry = 0
|
|
790
|
+
switch {
|
|
791
|
+
case sum < u_add {
|
|
792
|
+
new_carry = 1
|
|
793
|
+
}
|
|
794
|
+
case sum == u_add {
|
|
795
|
+
new_carry = add_carry as int
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
remainder.digits.store_int(wd_off + j + ai, sum as int)
|
|
799
|
+
add_carry = new_carry as uint64
|
|
800
|
+
}
|
|
801
|
+
var carry_idx = 0
|
|
802
|
+
while add_carry != 0 {
|
|
803
|
+
const uint64 u_carry = remainder.digits.load_int(wd_off + j + n + carry_idx) as uint64
|
|
804
|
+
const uint64 new_u = u_carry + add_carry
|
|
805
|
+
remainder.digits.store_int(wd_off + j + n + carry_idx, new_u as int)
|
|
806
|
+
if new_u >= u_carry {
|
|
807
|
+
add_carry = 0
|
|
808
|
+
}
|
|
809
|
+
carry_idx += 1
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
// Store quotient digit
|
|
814
|
+
self.ensure(j + 1)
|
|
815
|
+
self.set(j, q_hat)
|
|
816
|
+
}
|
|
817
|
+
self.len = m + 1
|
|
818
|
+
while self.len > 1 {
|
|
819
|
+
if self.get(self.len - 1) != 0 {
|
|
820
|
+
break
|
|
821
|
+
}
|
|
822
|
+
self.len -= 1
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
// Extract remainder from working dividend (normalized at wd_off..wd_off+n-1)
|
|
826
|
+
// Shift right by 'shift' to un-normalize
|
|
827
|
+
remainder.ensure(n)
|
|
828
|
+
remainder.len = n
|
|
829
|
+
if shift > 0 {
|
|
830
|
+
var uint64 r_carry = 0
|
|
831
|
+
var int ri = n - 1
|
|
832
|
+
while ri >= 0; ri -= 1 {
|
|
833
|
+
const uint64 val = remainder.digits.load_int(wd_off + ri) as uint64
|
|
834
|
+
remainder.set(ri, ((val >> shift) | r_carry))
|
|
835
|
+
r_carry = val << (64 - shift)
|
|
836
|
+
}
|
|
837
|
+
} else {
|
|
838
|
+
var ri = 0
|
|
839
|
+
while ri < n; ri += 1 {
|
|
840
|
+
const uint64 val = remainder.digits.load_int(wd_off + ri) as uint64
|
|
841
|
+
remainder.set(ri, val)
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
while remainder.len > 1 {
|
|
845
|
+
if remainder.get(remainder.len - 1) != 0 {
|
|
846
|
+
break
|
|
847
|
+
}
|
|
848
|
+
remainder.len = remainder.len - 1
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
pub func to_digit = (self, out int) {
|
|
853
|
+
if self.len == 1 {
|
|
854
|
+
return self.get(0) as int
|
|
855
|
+
}
|
|
856
|
+
return -1
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
pub func copy_from = (ref self, BigInt other) {
|
|
860
|
+
self.ensure(other.len)
|
|
861
|
+
self.len = other.len
|
|
862
|
+
self.sign = other.sign
|
|
863
|
+
var i = 0
|
|
864
|
+
while i < other.len; i += 1 {
|
|
865
|
+
self.set(i, other.get(i))
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
pub func set_int = (ref self, int val) {
|
|
870
|
+
self.sign = 1
|
|
871
|
+
var int v = val
|
|
872
|
+
if v < 0 {
|
|
873
|
+
self.sign = -1
|
|
874
|
+
v = 0 - v
|
|
875
|
+
}
|
|
876
|
+
self.ensure(1)
|
|
877
|
+
self.digits.store_int(0, v)
|
|
878
|
+
self.len = 1
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
pub func set_u64 = (ref self, uint64 val) {
|
|
882
|
+
self.sign = 1
|
|
883
|
+
self.ensure(1)
|
|
884
|
+
self.set(0, val)
|
|
885
|
+
self.len = 1
|
|
886
|
+
}
|
|
887
|
+
}
|