-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathint.lua
More file actions
1241 lines (1157 loc) · 52.6 KB
/
int.lua
File metadata and controls
1241 lines (1157 loc) · 52.6 KB
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
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
----------------------------------------------------
-- ULTIMATE INT --
----------------------------------------------------
-- MODULE VERSION: 186
-- BUILD VERSION: 186.7 (17/04/2026) dd:mm:yyyy
-- USER FEATURE: 26/11/2025
-- DEV FEATURE: 27/12/2025
-- AUTHOR: SupTan85
-- LICENSE: MIT (the same license as Lua itself)
-- LINK: https://github.com/SupTan85/int.lua
--
----------------------------------------------------
local intcur = -- 64 bit
(9223372036854775808 ~= 9223372036854775807 and {9, "9223372036854775808"}) or -- Lua 5.2 >=
(72057594037927936 ~= 72057594037927935 and {8, "72057594037927936"}) or
(9007199254740991 ~= 9007199254740990 and {7, "9007199254740991"}) or -- Lua 5.1 ==
-- 32 bit
{4, "2147483648"}
local master = {
_config = {
SETINTEGER_PERCHUNK = {
STABLE = 1,
BALANCE = math.floor(intcur[1] / 2),
FASTEST = intcur[1],
DEFAULT = intcur[1], -- recommend
},
OPTION = {
--[[ MASTER DIVISION | BYPASS GENERATE FLOATING POINT >>
How dose it work :
Optimize the division process by reducing the number of loop iterations. However, this approach may not be effective for very large numbers.
note: Some version of lua is not support this feature.
By SupTan85
<< BUILD-IN >>]]
MASTER_CALCULATE_DIV_BYPASS_GEN_FLOATING_POINT = true,
--[[ MASTER DIVISION | AUTO CONFIG ITERATIONS LIMIT >>
How dose it work :
automatic setting a maxiumum of iterations in division function. *only when there is no self config value*
note: this option causes a division speed slow, but very powerful for high accuracy.
// DISABLE : MASTER_CALCULATE_DIV_MAXITERATIONS
// DISABLE : MASTER_DEFAULT_FRACT_LIMIT_DIV
By SupTan85
<< BUILD-IN >>]]
MASTER_CALCULATE_DIV_AUTO_CONFIG_ITERATIONS = true,
MASTER_CALCULATE_DIV_AUTO_CONFIG_ITERATIONS_BUFF_MODE = false, -- use buff-accurate for more accuracy. note: very slow but high accuracy!
},
ACCURACY_LIMIT = {
-- MASTER FUNCTION CONFIG --
MASTER_CALCULATE_DIV_MAXITERATIONS = 15, -- 15
MASTER_CALCULATE_DIV_BUFF_ACCURATE = 2, -- 2
MASTER_DEFAULT_FRACT_LIMIT_DIV = 14, -- 14
-- MEDIA FUNCTION CONFIG --
MEDIA_DEFAULT_POWER_ACCURATE_LIMIT = 15, -- 15
MEDIA_DEFAULT_POWER_FRACT_LIMIT = 14, -- 14
MEDIA_DEFAULT_NATURAL_LOGARITHM_MAXITERATIONS = 15, -- 15
MEDIA_DEFAULT_EXPONENTIAL_MAXITERATIONS = 15, -- 15
MEDIA_DEFAULT_SQRTROOT_MAXITERATIONS = 15, -- 15
MEDIA_DEFAULT_SQRTROOT_TOLERANCE = 14, -- 14
},
-- SYSTEM CONFIG ! Internal use only, Do not modify. ! --
MAXIMUM_SIZE_PERCHUNK = intcur[1], -- stable size is 9
MAXIMUM_LUA_INTEGER = intcur[2] -- math.maxinteger
},
_VERSION = "186",
_BUILD = "186.7"
}
local OPTION = master._config.OPTION
local ACCURACY_LIMIT = master._config.ACCURACY_LIMIT
local OBJECT_CODENAME = "int object"
local OBJECT_PROFILE = ({(OBJECT_CODENAME):gsub("%s+", "-")})[1] -- auto create profile
---@diagnostic disable-next-line: deprecated
table.unpack = table.unpack or unpack
local max, min, floor, ceil = math.max, math.min, math.floor, math.ceil
local function sign(number) -- Returns -1 if `x < 0`, 0 if `x == 0`, or 1 if `x > 0`.
return (number == 0 and 0) or (number < 0 and -1 or 1)
end
local function istableobj(...) -- All value are table/int-object, else return false.
for _, v in ipairs({...}) do
local itype = type(v)
if itype ~= "table" and itype ~= OBJECT_CODENAME then
return false
end
end
return true
end
master.convert = function(st, s)
assert(type(st) == "string" or type(st) == "number", ("[CONVERT] INVALID_INPUT_TYPE | attempt to convert with a '%s'."):format(type(st)))
assert(type(st) == "number" or st:find("^%d*%.?%d*$"), ("[CONVERT] MALFORMED_NUMBER | function not support number format or input wans't number format. (%s)"):format(st))
st, s = tostring(st), s or 1
assert(not (s <= 0), ("[CONVERT] SETTING_SIZE_ISSUE | size per chunk is less then one. (%s < 1)"):format(s))
assert(not (s > master._config.MAXIMUM_SIZE_PERCHUNK), ("[CONVERT] INVALID_SIZE_PERCHUNK | size per chunk is more then maxiumum setting. (%s > %s)"):format(s, master._config.MAXIMUM_SIZE_PERCHUNK))
local result, step = {_size = s}, 0
local i, i2 = st:match("^0*(%d*)%.?(%d-)0*$")
i, i2 = (i or st):match("^0*(.-)$"):reverse(), i2 or ""
local len_i, len_i2 = #i, #i2
for index = 1, max(len_i, len_i2), s do
step = step + 1
if index <= len_i then
result[step] = tonumber(i:sub(index, min(index + s - 1, len_i)):reverse()) or error("[CONVERT] VOID_VALUE | attempt to convert but got 'nil'.")
end
if index <= len_i2 then
local d = i2:sub(index, min(index + s - 1, len_i2))
result[1 - step] = tonumber(d .. ("0"):rep(s - #d)) or error("[CONVERT] VOID_VALUE | attempt to convert but got 'nil'.")
result._dlen = 1 - step
end
end
result._dlen = result._dlen or 1
return result
end
master.deconvert = function(x)
-- BUILD 186.6
assert(istableobj(x or error("[DECONVERT] VOID_INPUT")), ("[DECONVERT] INVALID_INPUT_TYPE | attempt to deconvert with a '%s'."):format(type(x)))
local chunk_size = x._size or 1
local pattern_format = ("%%0%dd"):format(chunk_size)
local chunk_decimal = {}
local process = false
for i = x._dlen or 1, 0 do
local v = x[i] or error(("[DECONVERT] DAMAGED_OBJECT | missing decimal part value. index[%s]"):format(i))
assert(type(v) == "number", ("[DECONVERT] DAMAGED_OBJECT | detected invalid type in decimal part data. index[%s]: integer (not %s)"):format(i, type(v)))
local target = -i + 2
if process then
chunk_decimal[target] = pattern_format:format(v)
elseif v > 0 then
process = true
chunk_decimal[1] = "."
chunk_decimal[target] = pattern_format:format(v):match("^(%d-)0*$")
else
x[i] = nil
end
end
process = false
local chunk_integer = {}
for i = #x, 1, -1 do
local v = x[i] or error(("[DECONVERT] DAMAGED_OBJECT | missing integer path value. index[%s]"):format(i))
assert(type(v) == "number", ("[DECONVERT] DAMAGED_OBJECT | detected invalid type in integer part data. index[%s]: integer (not %s)"):format(i, type(v)))
local i = #x - i + 1
if process then
chunk_integer[i] = pattern_format:format(v)
elseif v > 0 then
process = true
chunk_integer[i] = pattern_format:format(v):match("^0*(%d-)$")
else
x[i] = nil
end
end
return (#chunk_integer > 0 and table.concat(chunk_integer) or "0")..(chunk_decimal[2] and table.concat(chunk_decimal) or "")
end
master.copy = function(x)
if istableobj(x) then
local copy = {}
for key, value in next, x, nil do
copy[key] = value
end
setmetatable(copy, getmetatable(x))
return copy
end
return x
end
local masterC, masterD = master.convert, master.deconvert
master.custom = {
_cfloor = function(x, length, resultonly, copy)
assert(type(length) == "number", ("[CFLOOR] INVALID_INPUT_TYPE | length: number (not %s)"):format(type(length)))
if length < 0 or length % 1 ~= 0 then
warn(("[CFLOOR] INVALID_INPUT | length: integer <positive> (current %s to %s)"):format(length, ceil(math.abs(length))))
length = ceil(math.abs(length))
end
local s, dlen, prlen = x._size or 1, x._dlen or 1, nil
local result = copy and {_size = s} or x
local new_dlen = floor(-length / s) + 1
if new_dlen >= dlen then
if copy then
for i = new_dlen, #x do
result[i] = x[i]
end
else
for i = dlen, new_dlen - 1 do
x[i] = nil
end
end
local rem_space = length % s
local shift = s - rem_space
if not resultonly then
local f, b = tostring(result[new_dlen]):find("0*$")
prlen = shift - (b - f + 1)
end
if rem_space > 0 then
local new_value = floor(result[new_dlen] * (10 ^ -shift)) * floor(10 ^ shift)
if new_value == 0 then
result[new_dlen] = nil
new_dlen = new_dlen + 1
else
result[new_dlen] = new_value
end
end
else
new_dlen = dlen
end
result._dlen = new_dlen
if resultonly then
return result
end
return result, new_dlen or dlen, prlen
end,
_refresh = function(x, lu, endp) -- refresh all chunk that should to be, by fast `ADD` process.
lu = lu or 0
local s, endp = x._size or 1, endp or x._dlen or 1
local re
local ca, sl = tostring(x[endp]):match("(%d-)0*$"):sub(1, -2), floor(10 ^ s)
re = tonumber(ca..("0"):rep(s - #ca)) + (lu * floor(10 ^ (s - #ca)))
x[endp], lu = re % sl, floor(re / sl)
if x[endp] == 0 then
x._dlen, x[endp] = x._dlen + 1, nil
end
while lu ~= 0 do
endp = endp + 1
re = (x[endp] or 0) + lu
x[endp], lu = re % sl, floor(re / sl)
if x[endp] == 0 then
x._dlen, x[endp] = x._dlen + 1, nil
end
end
x._dlen = max(endp, x._dlen)
return x
end,
_floor = function(x) -- Returns the largest integral value smaller than or equal to `x`.
assert(istableobj(x or error("[FLOOR] VOID_INPUT")), ("[FLOOR] INVALID_INPUT_TYPE | x: table/%s (not %s)"):format(OBJECT_PROFILE, type(x)))
for i = x._dlen or 1, 0 do
x[i] = nil
end
x._dlen = 1
return x
end,
cfloor = function(self, x, length) -- Custom a `x` decimal part. *use ":" to call a function*
assert(type(length) == "number", ("[CFLOOR] INVALID_INPUT_TYPE | length: number (not %s)"):format(type(length)))
assert(istableobj(x or error("[CFLOOR] VOID_INPUT")), ("[CFLOOR] INVALID_INPUT_TYPE | x: table/%s (not %s)"):format(OBJECT_PROFILE, type(x)))
return self._cfloor(x, length, true)
end,
cround = function(self, x, length, center) -- Custom a `x` decimal part, with automatic round system. (`center` The number of rounding centers) *use ":" to call a function*
assert(type(length) == "number", ("[CROUND] INVALID_INPUT_TYPE | length: number (not %s)"):format(type(length)))
assert(istableobj(x or error("[CROUND] VOID_INPUT")), ("[CROUND] INVALID_INPUT_TYPE | x: table/%s (not %s)"):format(OBJECT_PROFILE, type(x)))
local x, endp, prlen = table.unpack(length == -1 and {x, x._dlen or 1} or {self._cfloor(x, length + 1)})
if prlen and prlen >= 0 then
x = self._refresh(x, tostring(x[endp]):match("(%d)0*$") > (center and tostring(center) or "5") and 1 or 0, endp)
end
return x
end
}
local custom = master.custom
master.equation = {
equal = function(self, x, y) -- chunk size should be same
assert((x._size or 1) == (y._size or 1), ("[EQUATION] INVALID_SIZE_PERCHUNK (%s, %s)"):format(x._size or 1, y._size or 1))
if #x == #y and (x._dlen or 1) == (y._dlen or 1) then
for i = x._dlen or 1, #x do
if x[i] ~= y[i] then
return false
end
end
return true
end
return false
end,
less = function(self, x, y) -- chunk size should be same
-- BUILD 186.6
assert((x._size or 1) == (y._size or 1), ("[EQUATION] INVALID_SIZE_PERCHUNK (%s, %s)"):format(x._size or 1, y._size or 1))
if #x < #y then
return true
elseif #x == #y then
for i = #x, min((x._dlen or 1), (y._dlen or 1)) or 1, -1 do
local vx, vy = x[i] or 0, y[i] or 0
if vx ~= vy then
return vx < vy
end
end
end
return false
end,
more = function(self, x, y) -- chunk size should be same
return not self:less(x, y) and not self:equal(x, y)
end
}
master.concat = {
_creq = function(self, x, y, force)
assert(type(self) == "table" and self._seek and self._deep, "[CONCAT] BAD_FUNCTIONCALL | can't include required function")
assert(x and y, ("[CONCAT] VOID_INPUT |%s%s"):format(not x and " x: nil (input-required)" or "", not y and " y: nil (input-required)" or ""))
assert(istableobj(x), ("[CONCAT] INVALID_INPUT_TYPE | x: table/%s (not %s)"):format(OBJECT_CODENAME, type(x)))
assert(force or (istableobj(y) and (y._dlen or 1) >= 1) or (not istableobj(y) and tonumber(y) % 1 == 0), "[CONCAT] INVALID_INPUT | y: integer (not decimal)")
return true
end,
_deep = function(var, reverse, dlen) -- Returns number of chunk, that are start first.
-- BUILD 186.3
local dlen = dlen or var._dlen or 1
while var[dlen - 1] do
dlen = dlen - 1
end
if reverse then
for i = dlen, #var do
if var[i] ~= 0 then
return i
end
end
else
for i = #var, dlen, -1 do
if var[i] ~= 0 then
return i
end
end
end
var._dlen = dlen
return 1
end,
_seek = function(var, reqsize, offset, reverse, ignore) -- set and gets number position.
-- BUILD 186.3
assert(var and reqsize, ("[SEEK] VOID_INPUT |%s%s"):format(not var and " var: nil (input-required)" or "", not reqsize and " reqsize: nil (input-required)" or ""))
assert(tonumber(reqsize), ("[SEEK] INVALID_INPUT | reqsize: integer (not %s)"):format(type(reqsize)))
reqsize = tonumber(reqsize)
assert(reqsize % 1 == 0, "[SEEK] INVALID_INPUT | reqsize: integer (not decimal)")
if reqsize <= 0 then
return ""
end
offset = tonumber(offset) or 0
assert(offset % 1 == 0, "[SEEK] INVALID_INPUT | offset: integer (not decimal)")
if istableobj(var) then
local result = {}
local size, dlen = (var._size or 1), (var._dlen or 1)
local shift, skip = offset % size, floor(offset / size)
local index, pindex
local lstart, vlen = dlen + skip, #var
if offset > 0 and skip > 0 then
if not reverse then
shift = (size - #tostring(var[vlen])) + shift
elseif dlen < 1 then
local sel = tostring(var[dlen]):match("^.-(0*)$")
shift = #sel + shift
end
end
for i = lstart, vlen do
index = reverse and (index or 1) - 1 or (index or 0) + 1
if reqsize < 1 then
break
end
local i = reverse and (dlen - i) + vlen or i
local curr = tostring(var[i] or "")
if i ~= vlen then
curr = ("0"):rep(size - #curr)..curr
end
if not ignore and i == dlen and dlen < 1 then
curr = curr:match("^(.-)0*$")
end
local bsize = #curr
local include = curr:sub(reverse and -(shift + reqsize) or shift + 1, reverse and -(shift + 1) or shift + reqsize)
if pindex or #include > 0 then
pindex = reverse and (pindex or 1) - 1 or (pindex or 0) + 1
result[pindex] = include
end
reqsize = reqsize - max(bsize - shift, 0)
if shift > 0 then
shift = max(shift - bsize, 0)
end
end
return table.concat(result, nil, reverse and pindex or nil)
end
local result = tostring(var)
result = ignore and result:gsub("%.", "") or (result:match("^0*(%d+).?%d?") or "0")..(result:match("%d%.(%d*)0*$") or "")
return result:sub(reverse and -(offset + reqsize) or offset + 1, reverse and -(offset + 1) or offset + reqsize)
end,
left = function(self, x, y, ignore, shift, copy, force)
-- BUILD 186.3
assert(type(self) == "table" and self._creq and self:_creq(x, y, force), "[CONCAT] BAD_FUNCTIONCALL | can't include required function")
x = copy and master.copy(x) or x
shift = max(tonumber(shift) or 0, 0)
local i, istable = (not ignore and #x or self._deep(x)), istableobj(y)
local size = x._size or 1
local offset, ishift, skip = 0, shift % size, floor(shift / size)
if shift > 0 and skip > 0 then
if not ignore or (x._dlen or 1) >= 1 then
ishift = (#tostring(x[i] or "") % size) + ishift
elseif (x._dlen or 1) < 1 then
ishift = (#tostring(x[(x._dlen or 1)]) % size) + ishift
end
end
i = (#tostring(x[i]) >= size and i + 1 or i)
for i = i, i + (skip - 1) do
x[i] = x[i] or 0
end
i = i + skip
repeat
local curr = tostring(x[i] or "")
if ignore and curr == "0" then
curr = ""
end
if ishift > 0 then
local zshift = min(size - #curr, ishift)
curr = ("0"):rep(zshift)..curr
ishift = max(ishift - zshift, 0)
end
local nreq = size - #curr - ishift
local ireq = self._seek(y, nreq, offset, true, istable)
x[i] = tonumber(ireq..curr) or 0
i, offset = i + 1, offset + #ireq
until #ireq ~= nreq and ishift <= 0
return x
end,
right = function(self, x, y, ignore, shift, copy, force)
-- BUILD 186.3
assert(type(self) == "table" and self._creq and self:_creq(x, y, force), "[CONCAT] BAD_FUNCTIONCALL | can't include required function")
x = copy and master.copy(x) or x
shift = max(tonumber(shift) or 0, 0)
local dlen = x._dlen or 1
local i, istable = (not ignore and min(dlen, 0) or self._deep(x, true)), istableobj(y)
local size, dhead, xlogic = x._size or 1, i, (dlen < 1 and #x <= 1)
local offset, ishift, skip = 0, shift % size, floor(shift / size)
if shift > 0 and skip > 0 then
if ignore or xlogic then
ishift = (size - #tostring(x[i]):match("^.-(0*)$")) + ishift
end
end
for i = i, i - (skip - 1), -1 do
x[i] = x[i] or 0
end
i = i - skip
repeat
local curr = tostring(x[i] or "")
if i < dhead then
curr = curr:match("^(.-)0*$")
elseif ignore or xlogic then
local raw = curr:match("^(.-)0*$")
curr = ("0"):rep(size - #curr)..raw
end
if ishift > 0 then
local zshift = min(size - #curr, ishift)
curr = curr..("0"):rep(zshift)
ishift = max(ishift - zshift, 0)
end
local nreq = size - #curr - ishift
local ireq = self._seek(y, nreq, offset, false, istable)
x[i] = tonumber(curr..ireq..("0"):rep(size - (#curr + #ireq))) or 0
i, offset = i - 1, offset + #ireq
until #ireq ~= nreq and ishift <= 0
x._dlen = self._deep(x, true, i + 1)
return x
end,
-- auto = function(self, x, y, ignore, force) -- *this function was update `x` not return new object*
-- end
}
master.calculate = {
_verify = function(a, b, MAXIUMUM_SIZE, CODE_NAME)
assert(a and b, ("[%s] VOID_INPUT |%s%s"):format(CODE_NAME or "UNKNOW", not a and " a: nil (input-required)" or "", not b and " b: nil (input-required)" or ""))
assert(istableobj(a, b), ("[%s] INVALID_INPUT |%s%s"):format(CODE_NAME or "UNKNOW", istableobj(a) and "" or (" a: table/%s (not %s)"):format(OBJECT_PROFILE, type(a)), istableobj(b) and "" or (" b: table/%s (not %s)"):format(OBJECT_PROFILE, type(b))))
assert((a._size or 1) == (b._size or 1), ("[%s] INVALID_SIZE_PERCHUNK | _size: (%s != %s)"):format(CODE_NAME or "UNKNOW", a._size or 1, b._size or 1))
assert(not ((a._size or 1) > MAXIUMUM_SIZE), ("[%s] INVALID_SIZE_PERCHUNK | _size: (%s > %s)"):format(CODE_NAME or "UNKNOW", a._size or 1, MAXIUMUM_SIZE))
end,
add = function(self, a, b, s) -- _size maxiumum *2 **chunk size should be same**
self._verify(a, b, master._config.MAXIMUM_SIZE_PERCHUNK * 2, "ADD")
local result = {_size = a._size or s or 1}
local s, c, d = floor(10 ^ (result._size)), false, false
for i = min(a._dlen or 1, b._dlen or 1), max(#a, #b) do
local chunk_result = (a[i] or 0) + (b[i] or 0)
local next = floor(chunk_result / s)
result[i + 1] = (next ~= 0 and next) or nil
if i >= 1 or c == true or chunk_result ~= 0 then
result[i], c = (chunk_result % s) + (result[i] or 0), true
if d == false then
result._dlen = (i < 1 and i) or 1
d = true
end
end
end
return result
end,
sub = function(self, a, b, s) -- _size maxiumum *2 (to use this function `a >= b` else result will been wrong!) **chunk size should be same**
self._verify(a, b, master._config.MAXIMUM_SIZE_PERCHUNK * 2, "SUB")
local result = {_size = a._size or s or 1}
local s, d = floor(10 ^ (result._size)), false
local bottom_trim = false
for i = min(a._dlen or 1, b._dlen or 1), max(#a, #b) do
local chunk_result = (a[i] or 0) - (b[i] or 0)
local callback = (chunk_result % s) - (result[i] or 0)
local chunk_data = callback % s
bottom_trim = bottom_trim or chunk_data ~= 0
result[i] = bottom_trim and chunk_data or nil
if not d and bottom_trim then
result._dlen, d = (i < 1 and i) or 1, true
end
result[i + 1] = (callback < 0 and (floor((callback % s) / s) + (((callback % s) ~= 0 and 1) or 0))) or nil
result[i + 1] = (chunk_result < 0 and (result[i + 1] or 0) + (floor((chunk_result % s) / s) + (((chunk_result % s) ~= 0 and 1) or 0))) or result[i + 1]
end
for i = #result, 1, -1 do
if result[i] == 0 then
result[i] = nil
else
break
end
end
result._dlen = result._dlen or 1
return result
end,
mul = function(self, a, b, s, e) -- _size maxiumum *1 (`e` switch for division process.) **chunk size should be same**
-- BUILD 186.7
self._verify(a, b, master._config.MAXIMUM_SIZE_PERCHUNK, "MUL")
local result = {_size = a._size or s or 1}
local s, bottom = floor(10 ^ (result._size)), (a._dlen or 1) + (b._dlen or 1) - 1
for i = a._dlen or 1, #a do
local BA = a[i]
if BA and BA ~= 0 then
for i2 = b._dlen or 1, #b do
local calcul, offset = BA * (b[i2] or 0), i + i2 - 1
local chunk_data = (calcul + (result[offset] or 0))
-- print(offset, ("%09d"):format(BA), ("%09d"):format(b[i2] or 0), "=", calcul, "+", result[offset] or 0, "=", chunk_data)
local carry = floor(chunk_data / s)
result[offset] = chunk_data % s
local carry_i = 1
while carry > 0 do
local chunk_data = carry + (result[offset + carry_i] or 0)
carry = floor(chunk_data / s)
result[offset + carry_i] = chunk_data % s
carry_i = carry_i + 1
end
end
if e and #result >= 1 then -- optimize zone for div function
if (#result == 1 and result[1] ~= 0) then
break
end
local inlogic = false
for i = #result, 2, -1 do
local curr = result[i]
if curr ~= 0 then
inlogic = true
break
else
result[i] = nil
end
end
if inlogic then
break
end
end
end
result[i] = result[i] or 0
end
for i = #result, 1, -1 do
if result[i] == 0 then
result[i] = nil
else
break
end
end
for i = bottom, 0 do
if (result[i] or 0) ~= 0 then
result._dlen = i
break
else
result[i] = nil
end
end
result._dlen = result._dlen or 1
return result
end,
div = function(self, a, b, s, f, l) -- _size maxiumum *1 (`f` The maxiumum number of decimal part, `l` The maximum number of iterations to perform.) **chunk size should be same**
-- BUILD 186.7
self._verify(a, b, master._config.MAXIMUM_SIZE_PERCHUNK, "DIV")
assert(not master.equation:equal(b, masterC(0, b._size or 1)), "[DIV] INVALID_INPUT | divisor cannot be zero.")
local s, b_dlen, fv = a._size or s or 1, b._dlen or 1, f or (not OPTION.MASTER_CALCULATE_DIV_AUTO_CONFIG_ITERATIONS and ACCURACY_LIMIT.MASTER_DEFAULT_FRACT_LIMIT_DIV or 0)
local auto_acc, equation, concat = not l and OPTION.MASTER_CALCULATE_DIV_AUTO_CONFIG_ITERATIONS, master.equation, master.concat
local one = masterC(1, s)
local accuracy, uc = 0, 0
local lastpoint, fin, mark
local shift_mul = b_dlen < 1 and masterC("1"..("0"):rep((math.abs(min(b_dlen, 0)) * s) + #tostring(b[b_dlen])), s)
b = shift_mul and self:mul(b, shift_mul) or b
local d = OPTION.MASTER_CALCULATE_DIV_BYPASS_GEN_FLOATING_POINT and (function(b)
local p = b == "1" and "1" or tostring("1" / b)
if p:find("e") then
local L, R = p:match("^(%d-%.?%d+)e"), p:match("e%-?0*(%d+)$")
L, lastpoint = #L >= 4 and L:sub(1, -2) or L, #L >= 4 and L:sub(-2, -2) or (#L > 1 and L:sub(-1, -1) or L)
-- print(p, L, R, lastpoint)
local S = #L:match("^(%d+)%.?")
if R > master._config.MAXIMUM_LUA_INTEGER then
error("[DIV] OVERFLOW | division function can't handle this number, or something went wrong.")
end
return ("0."..("0"):rep(tonumber(R) - S)..(#L > 1 and L:gsub("%.", "") or L)):sub(1, -2)
elseif p ~= "0.0" and p ~= "0" then
if #p > 13 then
p = p:sub(1, -2)
end
lastpoint = p:sub(-1)
lastpoint = #lastpoint == 1 and lastpoint
return p
end
end)(masterD(b))
if not d then
local FLOAT = ((#b - 1) * s) + #tostring(b[#b]) - 2
d = FLOAT > 0 and "0."..("0"):rep(FLOAT)
end
local BUFF_ACCURATE_ENABLE = false
if auto_acc then
local function HF(x)
return (s - #tostring(x[#x])) + (x._dlen < 1 and s - #tostring(x[x._dlen] or "") or 0)
end
local AN, BN = (#a + math.abs((a._dlen or 1) - 1)) * s, (#b + math.abs(b_dlen - 1)) * s
local NV = AN > BN
if (NV and AN or BN) < tonumber(master._config.MAXIMUM_LUA_INTEGER) then
accuracy = (NV and AN or BN) - HF(NV and a or b) + fv + s + 2
else
error("[DIV] OVERFLOW | division function can't handle this number, or something went wrong.")
end
if OPTION.MASTER_CALCULATE_DIV_AUTO_CONFIG_ITERATIONS_BUFF_MODE then
BUFF_ACCURATE_ENABLE = true
end
else
accuracy = (l or ACCURACY_LIMIT.MASTER_CALCULATE_DIV_MAXITERATIONS) + 2
BUFF_ACCURATE_ENABLE = true
end
local F_LIMIT = f or accuracy - 2
local function check(n)
-- print("d =", d and masterD(d) or "nil")
local dc = d and setmetatable({}, {__index = d, __len = function() return #d end}) or masterC(n, s)
-- print(masterD(dc), masterD(d and concat:right(dc, n, false, uc, true) or dc))
local nc = self:mul(b, d and concat:right(dc, n, false, uc) or dc, s, true)
-- print(("n:%d = %s"):format(n, masterD(nc)))
if equation:more(nc, one) then
return 1
elseif equation:less(nc, one) then
return 0
end
end
local function calcu(c)
local map
if c then
map = {}
for i = 0, 9 do
map[i + 1] = (i % 2 ~= 0 and (c - ceil(i / 2)) or (c + ceil(i / 2))) % 10
end
else
map = {0, 1, 9, 2, 8, 3, 7, 4, 6, 5}
end
local high, low, code
for i = 1, 10 do
local i = map[i]
if i >= (low or 0) and i <= (high or 9) then
code = check(i)
if code == 0 then
low = i
elseif code == 1 then
high = i
else
return true, i
end
if (high or 9) - (low or 0) <= 1 and high and low then
break
end
end
end
-- print(high, low, code)
return false, low
end
if d then
if istableobj(d) then
local fp, bp = d[2], d[1]
accuracy = accuracy - masterD(bp)
d = {0, _size = s, _dlen = 1}
local SIZE = masterC(s, s)
while equation:less(bp, one) do
bp = self:sub(bp, SIZE)
if equation:less(bp, one) then
for v in fp:gmatch(("."):rep(s)) do
d._dlen = d._dlen - 1
d[d._dlen] = tonumber(v)
end
break
end
d._dlen = d._dlen - 1
d[d._dlen] = 0
end
else
d = d:sub(1, accuracy)
accuracy = accuracy - #(d:match("%.(.+)") or "")
d, lastpoint = masterC(d, s), lastpoint or d:match("(%d)0*$")
end
end
while accuracy > 0 do
local dv, lp = calcu(lastpoint)
-- issue checker >>
if not lp and master._config.OPTION.MASTER_CALCULATE_DIV_BYPASS_GEN_FLOATING_POINT then
io.write(("\n[DIV] VALIDATION_FAILED | issues detected in division function, main process is unable to find the correct result.\n\tFUNCTION LOG >>\nprocess: (%s / %s)\nraw_data: %s\n\n"):format((a and masterD(a)) or "ERROR", (b and masterD(b)) or "ERROR", (d and masterD(d)) or "ERROR"))
io.write("\n[DIV] VALIDATION_FAILED | issues detected in division function, main process is unable to find the correct result while using the option <MASTER_CALCULATE_DIV_BYPASS_GEN_FLOATING_POINT>.\nmodule will automatically disable this option permanent and recalculate the result again. some versions of Lua cannot using this option!\nset: master._config.OPTION.MASTER_CALCULATE_DIV_BYPASS_GEN_FLOATING_POINT = false\n")
master._config.OPTION.MASTER_CALCULATE_DIV_BYPASS_GEN_FLOATING_POINT = false
return master.calculate:div(a, b, s, f, l)
end
assert(lp, ("[DIV] VALIDATION_FAILED | issues detected in division function, main process is unable to find the correct result.\n\tFUNCTION LOG >>\nprocess: (%s / %s)\nraw_data: %s\n"):format((a and masterD(a)) or "ERROR", (b and masterD(b)) or "ERROR", (d and masterD(d)) or "ERROR"))
-- print((d and masterD(d)) or "ERROR")
-- issue checker <<
d, lastpoint = d and concat:right(d, lp, false, uc) or not d and masterC(lp, s) or d, lp
uc = lp == 0 and mark and (uc) + 1 or 0
mark = mark or d ~= nil
if dv then
lastpoint = nil
break
end
fin = fin or (masterD(d) or ""):match("^0*%.?0*$") == nil
if fin then
accuracy = accuracy - 1
end
end
-- Newton-Raphson --
-- x = x * (2 - a * x)
if BUFF_ACCURATE_ENABLE then
local TWO = masterC(2, s)
for _ = 1, ACCURACY_LIMIT.MASTER_CALCULATE_DIV_BUFF_ACCURATE do
local rap = self:sub(TWO, self:mul(b, d))
if rap._dlen >= 1 then
break
end
d = self:mul(d, rap)
end
end
--------------------
if shift_mul then
d = self:mul(d, shift_mul)
end
local raw = self:mul(a, d)
if F_LIMIT > 0 and lastpoint then
raw = custom:cround(raw, F_LIMIT)
end
return raw
end,
}
local media = {
assets = {
FSZero = function(...) -- update sign to plus when number is zero, for fix issue *zero*
local pack, cahce = {...}, nil
for i, v in ipairs(pack) do
cahce = cahce or masterC(0, v._size)
pack[i]._sign = master.equation:equal(v, cahce) and "+" or v._sign or "+"
end
return table.unpack(pack)
end,
EQMatch = function(n, e) -- check if n (int object) is equal e (number|string). *but not support decimal*
if n._dlen < 1 then
return false
end
e = tostring(e)
local n_size = n._size
local ipointer = 0
local e_len = e:len()
for i, v in ipairs(n) do
local current_chunk = tostring(v)
local current_cut = (i - 1) * n_size
for i2 = 1, n_size do
ipointer = ipointer + 1
local cut_as = current_cut + i2
if ipointer > e_len or e:sub(ipointer, ipointer) ~= current_chunk:sub(cut_as, cut_as) then
return false
end
end
end
return true
end
},
convert = function(n, size) -- automatic setup a table.
n = n or 0
local n_type = type(n)
assert(n_type == "string" or n_type == "number", ("[CONVERT] INVALID_INPUT_TYPE | n: string|number (not %s)"):format(n_type))
if tostring(n):find("e") then
n, n_type = tostring(n), "string"
local es, fs = tonumber(n:match("^%s*[+-]?%d+%.?%d*e([+-]?%d+)%s*$")), n:match("^%s*([+-]?%d+%.?%d*)e[+-]?%d+%s*$")
if es and fs then
if es ~= 0 then
local loc = (fs:find("%.") or (#fs + 1)) - 1
local dot, fs_sign = loc + es, fs:match("^%s*([+-])") or "+"
local f, b
fs = fs:gsub("%.", ""):gsub("[+-]", "")
if dot < 0 then
f, b = "0", ("0"):rep(-dot)..fs
else
fs = fs..("0"):rep(dot - #fs)
f, b = fs:sub(1, dot):match("^0*(.*)$"), fs:sub(dot + 1, -1):match("^(.-)0*$")
end
fs = fs_sign..(f == "" and "0" or f)..(b ~= "" and "."..b or "")
end
local t = masterC(fs:match("^%s*[+-]?(%d+%.?%d*)%s*$"), size)
t._sign = fs:match("^%s*([+-]?)") or "+"
return setmetatable(t, master._metatable)
end
error(("[CONVERT] VALIDATION_FAILED | malformed number near '%s'"):format(n:match("^%s*(.-)%s*$")))
end
local t = masterC(n_type == "string" and n:match("^%s*[+-]?(%d+%.?%d*)%s*$") or math.abs(tonumber(n) or error(("[CONVERT] MALFORMED_NUMBER '%s'"):format(n))), size)
t._sign = n_type == "string" and (n:match("^%s*([+-])") or "+") or sign(n) < 0 and "-" or "+"
return setmetatable(t, master._metatable)
end,
tostring = function(int) -- Deconvert table to string.
local str = masterD(int)
return (int._sign == "-" and str ~= "0" and "-" or "")..str
end,
abs = function(x) -- Returns the absolute value of `x`.
assert(istableobj(x), ("[ABS] INVALID_INPUT_TYPE | x: table/%s (not %s)"):format(OBJECT_PROFILE, type(x)))
x._sign = "+"
return setmetatable(x, master._metatable)
end,
fact = function(n, s) -- Factorial function
local result
if istableobj(n) then
result = setmetatable(masterC("1", n._size), master._metatable)
result._sign = "+"
else
n = setmetatable(masterC(n, s or master._config.SETINTEGER_PERCHUNK.DEFAULT), master._metatable)
result = setmetatable(masterC("1", s or master._config.SETINTEGER_PERCHUNK.DEFAULT), master._metatable)
n._sign, result._sign = "+", "+"
end
if n:eqmore(master._config.MAXIMUM_LUA_INTEGER) then
while n > 0 do
result, n = result * n, n - 1
end
else
n = tonumber(tostring(n))
while n > 0 do
result, n = result * n, n - 1
end
end
return result
end,
floor = function(x, length) -- Returns the largest integral value smaller than or equal to `x`, or Custom a `x` decimal part.
if x._sign == "-" then
if length then
---@diagnostic disable-next-line: param-type-mismatch
return setmetatable(custom:cround(x, length, 0), master._metatable)
end
return -((x._dlen or 1) < 1 and 1 or 0) + setmetatable(custom._floor(x), master._metatable)
end
return setmetatable(length and custom:cfloor(x, length) or custom._floor(x), master._metatable)
end,
cround = function(x, length) -- Custom a `x` decimal part, with automatic round system.
---@diagnostic disable-next-line: param-type-mismatch
return setmetatable(length and custom:cround(x, length) or custom._floor(x), master._metatable)
end,
ceil = function(x) -- Returns the smallest integral value larger than or equal to `x`.
return ((x._sign or "+") == "+" and (x._dlen or 1) < 1 and 1 or 0) + setmetatable(custom._floor(x), master._metatable)
end
}
local assets = media.assets
function media.equal(x, y) -- work same `equation:equal` but support sign config.
local ze, equation = masterC(0, x._size), master.equation
return (equation:equal(x, ze) and "+" or x._sign) == (equation:equal(y, ze) and "+" or y._sign) and equation:equal(x, y)
end
function media.less(x, y) -- work same `equation:less` but support sign config.
local xs, ys = assets.FSZero(x, y)
xs, ys = xs._sign, ys._sign
local nox = xs ~= ys
return nox and xs == "-" or (not nox and (xs == "-" and master.equation:more(x, y) or (xs ~= "-" and master.equation:less(x, y))))
end
function media.more(x, y) -- work same `equation:more` but support sign config.
local xs, ys = assets.FSZero(x, y)
xs, ys = xs._sign, ys._sign
local nox = xs ~= ys
return nox and xs == "+" or (not nox and (xs == "+" and master.equation:more(x, y) or (xs ~= "+" and master.equation:less(x, y))))
end
function media.integerlen(x) -- Returns number integer digits, that was in object.
local le = #x
return #tostring(x[le] or "") + ((media.convert(le, x._size) - 1):max(0) * x._size)
end
function media.decimallen(x) -- Returns number decimal digits, that was in object.
local le = x._dlen or 1
return le < 1 and #tostring(x[le] or ""):match("^(%d-)0*$") + ((media.convert(math.abs(le), x._size) - 1):max(0) * x._size) or media.convert(0, x._size)
end
function media.fdigitlen(x) -- Returns sum of number integer digits and number decimal digits.
return media.integerlen(x) + media.decimallen(x)
end
function media.tonumber(x) -- Deconvert table to number. *not recommend*
return tonumber(media.tostring(x))
end
function assets.vtype(...) -- asset for vtype function.
local stack, v = {...}, {...}
local SOFT, INTEGER = {table = 1}, master._config.SETINTEGER_PERCHUNK.DEFAULT
table.sort(v, function(a, b) return (SOFT[type(a)] or 0) > (SOFT[type(b)] or 0) end)
for _, s in ipairs(v) do
if istableobj(s) then
INTEGER = s._size or INTEGER
else
break
end
end
for i, s in ipairs(stack) do
local ty = type(s)
if ty == "string" or ty =="number" then
stack[i] = media.convert(s, INTEGER)
elseif istableobj(s) then
stack[i] = s
else
error(("[VTYPE] attempt to perform arithmetic on a (%s) value"):format(ty))
end
end
return stack
end
function media.vtype(...) -- This function make table can mix a number and string.
return table.unpack(assets.vtype(...))
end
function media.cdiv(x, y, f, l) -- Custom division function. (`f` The maxiumum number of decimal part, `l` The maximum number of iterations to perform.)
assert(x and y, "[CDIV] VOID_INPUT")
x, y = media.vtype(x, y)
local raw = master.calculate:div(x, y, x._size, f, l)
local x_sign, y_sign = x._sign or "+", y._sign or "+"
raw._sign = (#x_sign == 1 and x_sign or "+") == (#y_sign == 1 and y_sign or "+") and "+" or "-"
---@diagnostic disable-next-line: param-type-mismatch
return setmetatable(raw, master._metatable)
end
function media.sign(x) -- Returns -1 if x < 0, 0 if x == 0, or 1 if x > 0.
assert(x, "[SIGN] VOID_INPUT")
local siz = x._size or 1
local zeo = media.convert(0, siz)
local reg, req = media.more(x, zeo), media.equal(x, zeo)
local t = req and zeo or media.convert(1, siz)
t._sign = reg or req and "+" or "-"
return t
end
function media.max(x, ...) -- Returns the argument with the maximum value, according to the Lua operator `<`.
local result
for _, x in ipairs(assets.vtype(x, ...)) do
result = result and (media.more(result, x) and result) or x
end
return result and setmetatable(result, master._metatable)
end
function media.min(x, ...) -- Returns the argument with the minimum value, according to the Lua operator `>`.
local result
for _, x in ipairs(assets.vtype(x, ...)) do
result = result and (media.less(result, x) and result) or x
end
return result and setmetatable(result, master._metatable)
end
function media.ln(x, l) -- Returns the Natural logarithm of `x` in the given base. `l` The maximum number of iterations to perform.
x = media.vtype(x) or error("[IN] VOID_INPUT")
if tostring(x) <= "0" then
assert(tostring(x) ~= "0", "[IN] INVALID_INPUT | Natural logarithm function return inf-positive value.")
error("[IN] INVALID_INPUT | Natural logarithm function return non-positive value.")
end
local result = masterC(0, x._size)
result._sign = "+"
-- taylor series of logarithms --
local X1 = (x - 1) / (x + 1)
for n = 1, 1 + (2 * (l or ACCURACY_LIMIT.MEDIA_DEFAULT_NATURAL_LOGARITHM_MAXITERATIONS)), 2 do
result = result + ((1 / n) * (X1 ^ n))
end
return setmetatable(custom:cfloor(result * 2, 15), master._metatable)
end
function media.exp(x, l) -- Exponential function. `l` The maximum number of iterations to perform.
x = media.vtype(x) or error("[EXP] VOID_INPUT")
local result = setmetatable(masterC(0, x._size), master._metatable)
result._sign = "+"