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