· 5 years ago · Sep 17, 2020, 05:22 PM
1--[[
2 Big Number Library
3
4 made by idontthinkofacool and FoundForces, circa early 2020
5
6 Open-Source Version (May not include every functions that BigNum has)
7
8
9This piece of a module will let you store BigNum tables that are used in such a way that the number
10limit goes from 2^1024 (1.79e308) to 9.999999999 * 10^2^1024! (1e1.79e308) This is useful for these
11cases using {x, n} which is simply x * 10^n to store numbers, for example:
12
13Simulators
14
15Case 1: When you are working on a Saber Simulator and you have 18,000 players. Doing good. But then your
16players will reach 10^308 and will reach Infinity money then… People figure out how to fix the bug,
17but that is just the hard-coded ROBLOX limit! People start reporting the bug left and right, and you
18try to fix it but you just can't. Then, you start to lose players and your simulator dies. End of a
19game.
20
21Case 2: You are working on a Button Simulator, you have 60-70 players that are mostly Tycoon Sim players.
22You reach the 1e308 limit, and people are used to it! Until you add a couple more stats…
23People demand the 1e308 limit to be removed, then Button Simulator 3 did using a Beta version of this bignum,
24then your players start switching. Your Button Simulator will only have a few players, and it dies.
25End of a game, again.
26
27----------------------
28
29Messing With Scripts
30
31You might use this script to mess around with big numbers and tables. You can happily use it.
32As long as you do not break it, then you have to get another copy.
33
34
35More documentation at other points.
36
37How it Works, and advantage vs. other opensource BigNums
38
39How this works is that it store numbers instead of one double value, it's a table containing 2 elements.
40
41{E, D} = E * 10^D.
42
43Number Examples:
44
45{1, 0} = 1. {8, 3} = 8000. {6.5, 2} = 650. {2.345, 1} = 23.45. {8.21, 1900} = 8.21 * 10 ^ 1900.
46
47This can also handle really low numbers:
48
49{4.567876543, -2} = 0.04567876543. {0, anything} = 0. {2.34343434344334353, -16784} =
500.0000…0000234343434344334353 (16,783 zeroes).
51
52And negatives:
53
54{-b, c} = -(b * 10^c). This is how the number system works.
55
56----------------------
57
58Advantages:
59
60This is way faster (up to a few seconds on Extuls's BigNum on random e4000*e4000 numbers vs
61idontthinkofacool's random e10K*e10K numbers taking bare microseconds, as precision will take up
62more memory and exponentially more resources, so precision is limited to 2 NumberValues.) than
63competing bignums, and also has a higher limit (this BigNum has 10^10^308 limit, while other BigNums
64that are public have varying limits between 10^640 and 10^100000 (i choosed 10^100000 as it will take
65too long to compute adding or multiplying) while this one has a limit of 10^2^1024!).
66
67
68Unlike other BigNums, you CAN save the BigNum on a DataStore or a OrderedDataStore.
69Here's how:
70
71For a DataStore, you can save it by converting the BigNum to a string using the xN.bnumtostr function:
72
73local BigNum = require(game.ServerScriptService.BigNum)
74
75local BN2 = {8.10897029805, 11562} -- Example number
76
77BN2 = BigNum.bnumtostr(BN2) -- converts a table to a string "8.10897029805e11562" suitable for
78 --datastore saving without using up many DataStore characters. It can be easily halved by using a
79 --basic compression algorithm doing like this:
80
81{{0, "a"},{1,"b"},{2,"c"},etc.}
82
83--and converting the string to this table. You DO NOT need to do that,
84--this is a optional step.
85
86----------------------
87
88OrderedDataStore:
89
90local BigNum = require(game.ServerScriptService.BigNum)
91local BN2 = {8.108, 11562}
92
93--You can't save the BigNum and call it that. You can do this:
94
95BN2 = BigNum.log10(BigNum.add(BN2, {1, 0}))
96
97--This will increase the leaderboard limit from 2^64 to 10^308, but that's not enough… You must do it again:
98
99BN2 = BigNum.log10(BigNum.add(BN2, {1, 0}))
100
101--This will increase the leaderboard limit to 10^10^308. Always keep a note that there is unavoidable
102
103--accuracy issues with this BigNum as a compromise for this high limit and speed. You must add that once again:
104
105BN2 = BigNum.add(BN2, {1, 0})
106
107--You must convert that to a float, and multiply it by 29000000000000000:
108
109BN2 = BigNum.bnumtofloat(BN2) * 29000000000000000
110
111--Then you must save it as that. This is how it should look like:
112
113local BigNum = require(game.ServerScriptService.BigNum)
114
115local BN2 = {8.108, 11562}
116
117BN2 = BigNum.log10(BigNum.add(BN2, {1, 0}))
118
119BN2 = BigNum.log10(BigNum.add(BN2, {1, 0}))
120
121BN2 = BigNum.add(BN2, {1, 0})
122
123BN2 = BigNum.bnumtofloat(BN2) * 29000000000000000
124
125DataStore:SaveAsync(the key you want, BN2)
126
127--If you try to load, your values will be jumbled up. Here, we will be decoding this value:
128
129local Cash = data.Value
130
131Cash = Cash / 29000000000000000 -- to divide it.
132
133Cash = BigNum.floattobnum(Cash) -- to convert it back.
134
135BN2 = BigNum.sub(BN2, {1, 0}) -- to offset it closer to the right.
136
137BN2 = BigNum.pow({1, 1}, BN2) -- {1, 1} -> 10^BN2 to decode it once.
138
139BN2 = BigNum.sub(BN2, {1, 0}) -- to offset it even closer to the right.
140
141BN2 = BigNum.pow({1, 1}, BN2) -- {1, 1} -> 10^BN2 to decode it the last time.
142
143BN2 = BigNum.sub(BN2, {1, 0}) -- to fully decode it.
144
145--Then, you can use xN.short to make the value readable.
146
147You can also add new functions simply, but that will be explained later.
148
149----------------------
150
151Disadvantages:
152
153Compared to other BigNums, there are several compromises:
154
155For speed, the Precision goes from down to the last digit to normal precision. For some functions,
156precision gets worse the more it gets.
157
158For size, this has the same compromise as speed.
159
160For potential, it is harder to develop. Instead of doing {8, 147} ^ ({2.1, 4} + {8, 373} + {1, 1}),
161
162you need to do this: BigNum.pow({8, 147}, BigNum.add({2.1, 4}, BigNum.add({8, 373}, {1, 1}))).
163
164This is a neccessary compromise unless metatables are used, which is not used in sake for new functions
165being easier to add.
166
167
168----------------------
169
170
171
172-- How to Use --
173
174
175
176First, to add 2 numbers together (regular 8.85 + regular 5), you need to require the BigNum, convert
177normal numbers onto BigNums, then add it:
178
179local BigNum = require(game.ServerScriptService.BigNum)
180
181N1,N2 = 5,8.85
182
183N1 = BigNum.convert(N1) -- converts 5 to {5, 0}
184
185N2 = BigNum.convert(N2) -- converts 8.85 to {8.85, 0}
186
187N3 = BigNum.add(N1,N2) -- adds 5 and 8.85 = {1.385, 1}
188
189print(BigNum.bnumtostr(N3)) -- converts {1.385, 1} to string: 1.385e1
190
191It is harder to do becuse of how BigNum works. With extensive scripting knowledge, you may make it
192easy to use and distribute it.
193
194To compare, you must do:
195
196local w = require(game.ServerScriptService.BigNum)
197
198N1 = BigNum.convert("1.459e11") -- 145.9B
199
200N2 = BigNum.convert(-8979) -- -8979
201
202if BigNum.le(N2,N1) then --it is true
203
204 print("true")
205
206end
207
208----------------------
209
210 -- Converting a Game from Normal to BigNum --
211
212You only need to convert a game from Normal to BigNum ONCE. The diffucilty can vary game per game.
213On the easy end of the spectrum, it can take a few minutes to a hour to convert a simple idle game
214to BigNum.
215
216On the middle end of the spectrum, Button Simulator 3 took 3 days to convert from normal to BigNum
217thanks to it's Button Transformer, so only a few scripts getting converted was required. Otherwise,
218it would be at the other end of the spectrum:
219
220On the other end of the spectrum, if you have a game like Miner's Haven… oh boy. It can take upwards
221of a few MONTHS to a year to convert it fully. Miner's Haven tried to convert to a competing, older
222BigNum but failed. Make sure to check your game infastructure. If the configs are in-script, you are
223on this end of the spectrum.
224
225First, you must change player's NumberValues to StringValues (You store the values as strings).
226
227You may encounter many errors, so PLEASE
228MAKE A TESTING PLACE BEFORE YOU ATTEMPT TO CONVERT TO BIGNUM. Then, you might have a script like this:
229
230----------------------
231
232More documentation below this script. Have fun using this BigNum to create better games!
233
234
235-- List of all the function that are included: --
236
237-short(x) -- Converts a Bnum to a suffix, Example: short({1,3}) = 1K (1e3) ,, INPUT FORMAT: {X,N}
238
239-strtobnum(x) -- Converts a string to Bnum, Example: strtobnum( '1e4' ) = {1,4} ,, INPUT FORMAT: 'XeN'
240
241-floattobnum(x) -- Converts a number to Bnum, Example: bnumtofloat( 1000 ) = {1, 3} (1e3) ,, INPUT FORMAT: X
242
243-convert(x) -- Converts number/string to Bnum, Example: convert( '1e3' ) = {1,3} ,, INPUT FORMAT: X / 'XeN'
244
245-new(x, y) -- Makes a new bignum from 2 number, Example: new( 1, 3 ) = {1,3} (1e3) ,, INPUT FORMAT: X, N
246
247-bnumtofloat(x) -- Converts a Bnum to number, Example: bnumtofloat( {1,3} ) = 1000 ,, INPUT FORMAT: {X,N}
248
249-bnumtostr(x) -- Converts a Bnum to string, Example: bnumtostr( {1,3} ) = 1e3 ,, INPUT FORMAT: {X,N}
250
251-errorcorrection(x) -- Correct a Bnum (Very important), Example: errorcorrection({11, 2}) = {1.1,3} ,, INPUT FORMAT: {X,N}
252
253-div(x, y) -- Divides a Bnum with a Bnum, Example: div( {1,1}, {5,0} ) (10 / 5) = {2,0} (2) ,, INPUT FORMAT: {X,N} , {X,N}
254
255-mul(x, y) -- Multiplies a Bnum with a Bnum, Example: mul( {1,1}, {5,0} ) (10 * 5) = {5,1} (50) ,, INPUT FORMAT: {X,N} , {X,N}
256
257-log10(x) -- Gets the log10 of a Bnum, Example: log10( {1,2} ) (100) = {2,0} (2) ,, INPUT FORMAT: {X,N}
258
259-le(x, y) -- Is a Bnum smaller then a Bnum, Example: le( {1,1}, {9,0} ) (10 < 9) = false ,, INPUT FORMAT: {X,N} , {X,N}
260
261-me(x, y) -- Is a Bnum bigger then a Bnum, Example: le( {1,1}, {9,0} ) (10 > 9) = true ,, INPUT FORMAT: {X,N} , {X,N}
262
263-eq(x, y) -- Is a Bnum equal to a Bnum, Example eq( {1,0}, {1,0} ) = true ,, INPUT FORMAT: {X,N} , {X,N}
264
265-add(x, y) -- Adds a Bnum with a Bnum, Example: add( {1,1}, {5,0} ) (10 + 5) = {1.5,1} (15) ,, INPUT FORMAT: {X,N} , {X,N}
266
267-sub(x, y) -- Subtracts a Bnum with a Bnum, Example: sub( {1,1}, {5,0} ) (10 - 5) = {5,0} (5) ,, INPUT FORMAT: {X,N} , {X,N}
268
269-sqrt(x) -- Gets the Square root of a Bnum, Example: sqrt( {1.6,1} ) (16) = {4,0} (4) ,, INPUT FORMAT: {X,N}
270
271-log(x) -- Gets log of a Bnum, Example: log( {1,2} ) (100) = {4.6051, 0} (4.6051) ,, INPUT FORMAT: {X,N}
272
273-abs(x) -- Gets absolute value of a Bnum, Example: abs( {-3, 0} ) (-3) = {3,0} ,, INPUT FORMAT: {X,N}
274
275-shift(x, y) -- Round a Bnum to y decimal places, Example: shift( {3.12, 0} ) (3.12) = {3,0} ,, INPUT FORMAT: {X,N} , X
276
277-pow(x, y) -- Does Bnum to the power of Bnum, Example: pow( {2, 0} , {2, 0} ) (2) (2) = {4,0} (4) ,, INPUT FORMAT: {X,N} , {X,N}
278
279-rand(min, max) -- Gets a random Bnum bewteen min and max, Example: rand( {0,0}, {9,0} ) (0) (9) = {5.16443014098954, 0} ,, INPUT FORMAT: {X,N} , {X,N}
280
281-floor(x) -- Floors a Bnum, Example: floor( {9.1, 0} ) (9.1) = {9 , 0} (9) ,, INPUT FORMAT: {X,N}
282
283]]--
284
285
286---------------------- BigNum it self
287
288
289local xN = {}
290function xN.short(bnum)
291 --[[
292
293 xN.short(bnum).
294
295 Description:
296 Shorts the BigNum onto a suffix, like modern games, simulators, tycoons or modern talking
297 today use auto-generated suffixes. The Open-Source version includes suffixes up to and
298 including 10^3,000,000,000,000. To add more, you can put more suffixes on MultOnes. This
299 may error and break scripts if you try and xN.short more than it can handle. You can add
300 more suffixes by adding things onto table MultOnes. Make sure to not add more than 102
301 entries onto MultOnes otherwise the 103rd entry and higher will be over the BigNum limit
302 and will not be used.
303
304 Examples:
305 {8.65, 282} -> 8.65e282. 279 / 3 = 93, so put the 9th on the SecondOnes and 3rd on the
306 FirstOnes, but NOT the 3rd one. Result: 8.65TNg
307
308 {2.13374, 283}, 280 / 3 = 93 remainder 1, so put the 9th on the SecondOnes and 3rd on the
309 FirstOnes, but NOT the 3rd one. Instead of 2.13TNg, it is multiplied by 10^remainder and
310 only 2 decimal places are shown. Result: 21.33TNg
311
312 {9.4811852, 2}, -1 / 3 = -1 remainder 2. Since it is below 0, just put 9.4811 * 10^2.
313 Result: 948.11
314 {4, 4}. 1 / 3 = 0 remainder 1. There is cases where x/3 are lower or equal to 2 remainder 2.
315 If the standard case was applied to remainder 1, it would be called "40U", but that is not
316 what it is called. The backup is applied instead of U, so it's "40k".
317 {1.23456, 78907} = 78904 / 3 = 26301 remainder 1. It applies the SecondOnes #2 and FirstOnes
318 #6 so "VtSx". But unlike the normal ones, it uses the first MultOnes, which is "Mi". So, it
319 becomes "VtSxMi". Then, it returns back to ThirdOnes, so it uses 3rd ThirdOnes which is "Tr".
320 It knows it can't use the 0th SecondOnes, so it's "VtSxMiTr". It uses the first FirstOnes but
321 does NOT use it AFTER, but BEFORE the Tr, so it's "VtSxMiUTr". Finally, it merges it as normal.
322 Result: "12.34VtSxMiUTr".
323
324
325
326
327 ]]--
328 bnum = xN.errorcorrection(bnum)
329 local SNumber = bnum[2]
330 local SNumber1 = bnum[1]
331 local leftover = math.fmod(SNumber, 3)
332 SNumber = math.floor(SNumber / 3)
333 SNumber = SNumber - 1
334 if SNumber <= -1 then
335 return math.floor(xN.bnumtofloat(bnum) * 100) / 100
336 end
337 local FirstOnes = {"", "U","D","T","Qd","Qn","Sx","Sp","Oc","No"}
338 local SecondOnes = {"", "De","Vt","Tg","qg","Qg","sg","Sg","Og","Ng"}
339 local ThirdOnes = {"", "Ce", "Du","Tr","Qa","Qi","Se","Si","Ot","Ni"}
340 local MultOnes = {"", "Ma", "Ma^2", "Ma^3", "Ma^4", "Ma^5", "Ma^6", "Ma^7", "Ma^8", "Ma^9", "Ma^10", "Ma^11", "Ma^12", "Ma^13",
341 "Ma^14", "Ma^15", "Ma^16", "Ma^17", "Ma^18", "Ma^19", "Ma^20", "Ma^21", "Ma^22", "Ma^23", "Ma^24", "Ma^25", "Ma^26", "Ma^27",
342 "Ma^28", "Ma^29", "Ma^30", "Ma^31", "Ma^32", "Ma^33", "Ma^34", "Ma^35", "Ma^36", "Ma^37", "Ma^38", "Ma^39", "Ma^40", "Ma^41",
343 "Ma^42", "Ma^43", "Ma^44", "Ma^45", "Ma^46", "Ma^47", "Ma^48", "Ma^49", "Ma^50", "Ma^51", "Ma^52", "Ma^53", "Ma^54", "Ma^55",
344 "Ma^56", "Ma^57", "Ma^58", "Ma^59", "Ma^60", "Ma^61", "Ma^62", "Ma^63", "Ma^64", "Ma^65", "Ma^66", "Ma^67", "Ma^68", "Ma^69",
345 "Ma^70", "Ma^71", "Ma^72", "Ma^73", "Ma^74", "Ma^75", "Ma^76", "Ma^77", "Ma^78", "Ma^79", "Ma^80", "Ma^81", "Ma^82", "Ma^83",
346 "Ma^84", "Ma^85", "Ma^86", "Ma^87", "Ma^88", "Ma^89", "Ma^90", "Ma^91", "Ma^92", "Ma^93", "Ma^94", "Ma^95", "Ma^96", "Ma^97",
347 "Ma^98", "Ma^99", "Ma^100", "Ma^101"}
348 if bnum[2] == 1/0 then
349 if bnum[1] < 0 then
350 return "-Infinity"
351 else
352 return "Infinity"
353 end
354 end
355 -- suffix part
356 if SNumber == 0 then
357 return math.floor(SNumber1 * 10^leftover * 100)/100 .. "k"
358 elseif SNumber == 1 then
359 return math.floor(SNumber1 * 10^leftover * 100)/100 .. "M"
360 elseif SNumber == 2 then
361 return math.floor(SNumber1 * 10^leftover * 100)/100 .. "B"
362 end
363 local txt = ""
364
365 local function suffixpart(n)
366
367 local Hundreds = math.floor(n/100)
368 n = math.fmod(n, 100)
369 local Tens = math.floor(n/10)
370 n = math.fmod(n, 10)
371 local Ones = math.floor(n/1)
372
373 txt = txt .. FirstOnes[Ones + 1]
374 txt = txt .. SecondOnes[Tens + 1]
375 txt = txt .. ThirdOnes[Hundreds + 1]
376
377 end
378 local function suffixpart2(n)
379 if n > 0 then
380 n = n + 1
381 end
382 if n > 1000 then
383 n = math.fmod(n, 1000)
384 end
385 local Hundreds = math.floor(n/100)
386 n = math.fmod(n, 100)
387 local Tens = math.floor(n/10)
388 n = math.fmod(n, 10)
389 local Ones = math.floor(n/1)
390
391 txt = txt .. FirstOnes[Ones + 1]
392 txt = txt .. SecondOnes[Tens + 1]
393 txt = txt .. ThirdOnes[Hundreds + 1]
394
395 end
396
397 if SNumber < 1000 then
398 suffixpart(SNumber)
399 return math.floor(SNumber1 * 10^leftover * 100)/100 .. txt
400 end
401
402 for i=#MultOnes,0,-1 do
403 if SNumber >= 10^(i*3) then
404 suffixpart2(math.floor(SNumber / 10^(i*3))- 1)
405 txt = txt .. MultOnes[i+1]
406
407 SNumber = math.fmod(SNumber, 10^(i*3))
408 end
409 end
410 return math.floor(SNumber1 * 10^leftover * 100)/100 .. txt
411end
412
413
414function xN.strtobnum(str)
415 --[[
416 xN.strtobnum(str). Takes strings instead of BigNums.
417
418 Description:
419 Converts a string "4.21897632e11561178" onto a BigNum usable with this BigNum. This
420 is the only valid format, and "2.62716e+1753" does NOT work.
421 Examples:
422 "1.72e18" gets converted to {1.72, 18}
423 "-8.88e-888" gets converted to {-8.88, -888}.
424 "2.147483648e-1.23456789e+123" gets converted to {2.147483648, -1.23456789e+123} or
425 2.147483648 * 10^-(1.23 * 10^123).
426
427
428
429 ]]--
430 local Synapse = string.find(str, "e")
431 return {tonumber(string.sub(str, 1, Synapse-1)), tonumber(string.sub(str, Synapse+1))}
432end
433
434function xN.bnumtofloat(bnum)
435 --[[
436 xN.bnumtofloat(str)
437
438 Description:
439 Converts a BigNum back to a normal number with the normal 1.79e308 cap.
440
441 Examples:
442 {8.2813, 21} gets converted back to 8281299999999999868928 beacuse of
443 unavoidable floating-point precision,
444 {-4.5, 12} gets converted back to -4500000000000.
445 {1.4, 0} gets converted back to 1.39999999999999991118215802999 beacuse
446 of the same thing as {8.2813, 21}.
447
448 Exceptions:
449 Any numbers not in the normal limit are converted to "inf". or "-inf".
450 Please take notice.
451 {8.72, 321} gets converted back to inf beacuse of this exception.
452 ]]--
453 return tonumber(xN.bnumtostr(bnum))
454end
455
456function xN.convert(str)
457 --[[
458 xN.convert(str)
459
460 Description:
461 The main API to convert a string OR a number to BigNum. It is recommended to
462 use this function to convert it to usable BigNum.
463
464 Examples:
465 "2.227175e1892" gets converted to {2.227175, 1892}.
466 -3.717e16 gets converted to {-3.717, 16}.
467 0.8 gets converted to {8, -1}.
468 "0.922318e1" gets convertetd to {0.922318, 1} which is invalid. Use error correction
469 to fix it.
470 Exceptions:
471 If you try to convert normal number inf, it gets converted to {1, 1.797693e308}
472 beacuse it's already inf.
473 ]]--
474 if tonumber(str) == nil then
475 local V,Uw = pcall(function()
476 return xN.strtobnum(str)
477 end)
478 if V then
479 return xN.strtobnum(str)
480 else
481 return "0"
482 end
483 end
484 if type(str) == "number" then
485 if tonumber(str) == 1/0 or tonumber(str) == -1/0 then
486 return {1, 1.797693e308}
487 end
488 end
489 if tonumber(str) == 1/0 or tonumber(str) == -1/0 then
490 return xN.strtobnum(str)
491
492 elseif tostring(tonumber(str)) == "nil" then
493 return xN.strtobnum(str)
494 else
495
496 return xN.floattobnum(tonumber(str))
497 end
498
499end
500
501function xN.new(man,exp)
502 --[[
503 xN.new(man,exp)
504
505 Description:
506 Creates a brand new BigNum man * 10^exp.
507
508 Examples:
509 xN.new( 1, 2) creates { 1, 2} or 100.
510 xN.new(-6,-7) creates {-6,-7} or -0.0000006.
511
512 ]]--
513 return {man, exp}
514end
515
516function xN.floattobnum(float)
517 --[[
518 xN.floattobnum(float)
519
520 Description:
521 Converts normal number 'float' onto BigNum.
522
523 Examples:
524 1.6180933 gets converted to {1.6180933, 0}.
525 23456652.18 gets converted to {2.345665218, 7}.
526 -89000 gets convertetd to {-8.9, 4}.
527 -1.286e-182 gets converted to {-1.286, -182}.
528
529 Exception:
530 Unpredictable results can happen when converting inf.
531
532 ]]--
533 local ZeN = tostring(float)
534 local Synapse = string.find(ZeN, "+")
535 if Synapse then
536 return xN.strtobnum(string.sub(ZeN, 1, Synapse-1) .. string.sub(ZeN, Synapse+1))
537 elseif string.find(ZeN, "e") then
538 return xN.strtobnum(ZeN)
539 else
540 return xN.errorcorrection(xN.strtobnum(ZeN .. "e0") )
541 end
542end
543
544function xN.bnumtostr(bnum)
545 --[[
546 xN.bnumtostr(bnum)
547
548 Description:
549 Converts BigNum to a string. It is strongly used for saving and storing BigNums.
550 ]]--
551 return tostring(bnum[1]) .. "e" .. tostring(bnum[2])
552end
553
554
555function xN.errorcorrection(bnum)
556 --[[
557 xN.errorcorrection(bnum)
558
559 Description:
560 Errorcorrects BigNums. Without this, this BigNum would not even be possible.
561 All things are error corrected.
562
563
564 ]]--
565 local signal = "+"
566 if bnum[1] == 0 then
567 return {0, 0}
568 end
569 if bnum[1] < 0 then
570 signal = "-"
571 end
572 if signal == "-" then
573 bnum[1] = bnum[1] * -1
574 -- Preparing for the worst to come.
575 end
576 -- get bnum ecc
577 local signal2 = "+"
578 if bnum[2] < 0 then
579 signal2 = "-"
580 bnum[2] = bnum[2] * -1
581 end
582 if math.fmod(bnum[2], 1) > 0 then
583 bnum[1] = bnum[1] * (10^ (1 - math.fmod(bnum[2], 1)))
584 bnum[2] = math.floor(bnum[2]) + 1
585 end
586 if signal2 == "-" then
587 bnum[2] = bnum[2] * -1
588 end
589 -- get digit after digits
590 local DgAmo = math.log10(bnum[1])
591 DgAmo = math.floor(DgAmo)
592 bnum[1] = bnum[1] / 10^DgAmo
593 bnum[2] = bnum[2] + DgAmo
594 bnum[2] = math.floor(bnum[2])
595 -- do not forget signals!
596 if signal == "-" then
597 bnum[1] = bnum[1] * -1
598 end
599 return bnum
600end
601
602function xN.div(bnum1, bnum2)
603 --[[
604 xN.div(bnum1, bnum2)
605
606 Description:
607 Divides 2 BigNums.
608
609 ]]--
610 bnum1 = xN.errorcorrection(bnum1)
611 bnum2 = xN.errorcorrection(bnum2)
612 local bnum3 = xN.new(0, 0)
613 bnum3[1] = bnum1[1] / bnum2[1]
614 bnum3[2] = bnum1[2] - bnum2[2]
615 bnum3 = xN.errorcorrection(bnum3)
616 return bnum3
617end
618
619function xN.mul(bnum1, bnum2)
620 --[[
621 xN.mul(bnum1, bnum2)
622
623 Description:
624 Multiplies 2 BigNums.
625
626 ]]--
627 bnum1 = xN.errorcorrection(bnum1)
628 bnum2 = xN.errorcorrection(bnum2)
629 local bnum3 = xN.new(0, 0)
630 bnum3[1] = bnum1[1] * bnum2[1]
631 bnum3[2] = bnum1[2] + bnum2[2]
632 bnum3 = xN.errorcorrection(bnum3)
633 return bnum3
634end
635
636function xN.log10(bnum)
637 --[[
638 xN.log10(bnum1, bnum2)
639
640 Description:
641 Gets the log10 of the BigNum.
642
643 ]]--
644 local LogTen = bnum[2] + math.log10(bnum[1])
645 return xN.errorcorrection(xN.new(LogTen, 0))
646end
647
648function xN.eq(bnum1, bnum2)
649 --[[
650 xN.eq(bnum1, bnum2) (DOES NOT RETURN BIGNUM)
651
652 Description:
653 Returns true if bnum1 is the same as bnum2, otherwise returns false.
654
655 ]]--
656 bnum1 = xN.errorcorrection(bnum1)
657 bnum2 = xN.errorcorrection(bnum2)
658 if bnum1[1] == bnum2[1] then
659 if bnum1[2] == bnum2[2] then
660 return true
661 end
662 end
663 return false
664end
665
666function xN.le(bnum1, bnum2)
667 --[[
668 xN.le(bnum1, bnum2) (DOES NOT RETURN BIGNUM)
669
670 Description:
671 Returns true if bnum1 is less than bnum2, otherwise returns false.
672
673 ]]--
674 bnum1 = xN.errorcorrection(bnum1)
675 bnum2 = xN.errorcorrection(bnum2)
676 local signal = "+"
677 local signal2 = "+"
678 if bnum1[1] < 0 then
679 signal = "-"
680 end
681 if bnum2[1] < 0 then
682 signal2 = "-"
683 end
684 if signal == "+" and signal2 == "-" then
685 return false
686 elseif signal == "-" and signal2 == "+" then
687 return true
688 elseif signal == "-" and signal2 == "-" then
689 if bnum1[2] > bnum2[2] then
690 -- passed test 1.
691 return true
692 end
693 if bnum1[2] < bnum2[2] then
694 -- passed test 1.
695
696 return false
697 end
698 if bnum1[1] < bnum2[1] then
699 -- passed test 2.
700 return true
701 end
702 elseif signal == "+" and signal2 == "+" then
703 if bnum1[2] < bnum2[2] then
704 -- passed test 1.
705 return true
706 end
707 if bnum1[2] > bnum2[2] then
708 -- passed test 1.
709
710 return false
711 end
712 if bnum1[1] < bnum2[1] then
713 -- passed test 2.
714 return true
715 end
716 end
717 return false
718end
719
720function xN.me(bnum1, bnum2)
721 --[[
722 xN.me(bnum1, bnum2) (DOES NOT RETURN BIGNUM)
723
724 Description:
725 Returns true if bnum1 is more than bnum2, otherwise returns false.
726
727 ]]--
728
729 bnum1 = xN.errorcorrection(bnum1)
730 bnum2 = xN.errorcorrection(bnum2)
731 local signal = "+"
732 local signal2 = "+"
733 if bnum1[1] < 0 then
734 signal = "-"
735 end
736 if bnum2[1] < 0 then
737 signal2 = "-"
738 end
739 if signal == "+" and signal2 == "-" then
740 return true
741 elseif signal == "-" and signal2 == "+" then
742 return false
743 elseif signal == "-" and signal2 == "-" then
744 if bnum1[2] < bnum2[2] then
745 -- passed test 1.
746 return true
747 end
748 if bnum1[2] < bnum2[2] then
749 -- passed test 1.
750
751 return false
752 end
753 if bnum1[1] > bnum2[1] then
754 -- passed test 2.
755 return true
756 end
757 elseif signal == "+" and signal2 == "+" then
758
759
760 if bnum1[2] > bnum2[2] then
761 -- passed test 1.
762
763 return true
764 end
765 if bnum1[2] < bnum2[2] then
766 -- passed test 1.
767
768 return false
769 end
770
771 if bnum1[1] > bnum2[1] then
772 -- passed test 2.
773
774 return true
775
776 end
777
778 end
779 return false
780end
781
782
783function xN.add(bnum1, bnum2)
784 --[[
785 xN.add(bnum1, bnum2)
786
787 Description:
788 The simplest of them all. Adds two BigNums together.
789 ]]--
790 bnum1 = xN.errorcorrection(bnum1)
791 bnum2 = xN.errorcorrection(bnum2)
792 local bnum3 = xN.new(0,0)
793 local Diff = bnum2[2] - bnum1[2]
794 if Diff > 20 then
795 return bnum2
796 elseif Diff < - 20 then
797 return bnum1
798 else
799 bnum3[2] = bnum1[2]
800 bnum3[1] = bnum1[1] + (bnum2[1] * 10^Diff)
801 end
802 bnum3 = xN.errorcorrection(bnum3)
803 return bnum3
804end
805
806
807function xN.sub(bnum1, bnum2)
808 --[[
809 xN.sub(bnum1, bnum2)
810
811 Description:
812 Substracts the second BigNum from the first BigNums.
813 ]]--
814 bnum1 = xN.errorcorrection(bnum1)
815 bnum2 = xN.errorcorrection(bnum2)
816 local bnum3 = xN.new(0,0)
817 local Diff = bnum2[2] - bnum1[2]
818 if Diff > 20 then
819 bnum3 = xN.new(bnum1[1] * -1, bnum2[2])
820 elseif Diff < - 20 then
821 return bnum1
822 else
823 bnum3[2] = bnum1[2]
824 bnum3[1] = bnum1[1] - (bnum2[1] * 10^Diff)
825 end
826 bnum3 = xN.errorcorrection(bnum3)
827 return bnum3
828end
829
830
831function xN.pow(bnum1, bnum2)
832 --[[
833 xN.pow(bnum1, bnum2)
834
835 Description:
836 Substracts the second BigNum from the first BigNums.
837
838 Exceptions:
839 Negative exponenting (-4)^x is not supported, and will put {1,nil} instead.
840
841 ]]--
842 if bnum1[1] < 0 then
843 -- warn("Negative exponenting is not supported on this BigNum.")
844 return {1,nil}
845 end
846 if bnum1[1] == 0 and bnum2[2] == 0 then
847 -- warn("I agree that 0 ^ 0 is 0.5")
848 return {0.5, 0}
849 elseif bnum2[1] == 0 then
850 return {1, 0}
851 elseif bnum1[1] == 0 then
852 return {0, 0}
853
854 end
855
856 bnum1 = xN.errorcorrection(bnum1)
857 bnum2 = xN.errorcorrection(bnum2)
858 local bnum3 = {0, 0}
859 local N = xN.log10(bnum1)
860 N = xN.bnumtofloat(N)
861 N = N * xN.bnumtofloat(bnum2)
862 bnum3[2] = N
863 --bnum3[2] = math.floor(N)
864 bnum3[1] = 1
865 return xN.errorcorrection(bnum3)
866end
867
868
869function xN.sqrt(bnum1)
870 --[[
871 xN.sqrt(bnum1)
872
873 Description:
874 Returns the square root of a BigNum.
875 ]]--
876 bnum1 = xN.errorcorrection(bnum1)
877 return xN.pow(bnum1, {5, -1})
878end
879
880
881
882
883function xN.log(bnum)
884 --[[
885 xN.log(bnum1)
886
887 Description:
888 Returns the natural logarthim of a BigNum.
889 ]]--
890 local b = xN.bnumtofloat({2.718281828045905, 0})
891 local LogTen = bnum[2] + math.log10(bnum[1])
892 LogTen = LogTen / math.log10(b)
893 return xN.errorcorrection(xN.new(LogTen, 0))
894end
895
896
897function xN.rand(bnum1, bnum2)
898 --[[
899 xN.rand(bnum1, bnum2)
900
901 Description:
902 Returns a random BigNum between bnum1 and bnum2.
903 ]]--
904 local Ye = xN.convert(math.random())
905
906 local bnum3 = xN.mul(Ye, xN.sub(bnum1, bnum2))
907 bnum3 = xN.add(bnum3, bnum2)
908 return bnum3
909end
910
911
912
913function xN.abs(bnum1)
914 --[[
915 xN.rand(bnum1)
916
917 Description:
918 Returns the absolute value of a BigNum.
919 ]]--
920 return {math.abs(bnum1[1]), bnum1[2]}
921end
922
923function xN.floor(bnum1)
924 --[[
925 xN.rand(bnum1)
926
927 Description:
928 Returns the absolute value of a BigNum.
929 ]]--
930 if bnum1[2] > 15 then
931 return bnum1
932 end
933 return xN.convert(math.floor(xN.bnumtofloat(bnum1)))
934end
935
936
937
938function xN.meeq(bnum, bnum1) -- more or equal to
939
940 if xN.me(bnum, bnum1) or xN.eq(bnum, bnum1) then -- check if its bigger or equal to
941
942 return true -- if so return true
943
944 end
945
946return false -- otherwise return false
947
948end -- close function
949
950
951return xN