Thanks to visit codestin.com
Credit goes to www.scribd.com

0% found this document useful (0 votes)
15 views20 pages

Message

The document describes the EternityNum library, which is designed to handle extremely large numbers up to 10↑↑2^1024. It includes various functions for checking, converting, and calculating with EternityNum values, as well as handling special cases like NaN and Infinity. The library provides a structured way to represent and manipulate these large numbers using a specific format.

Uploaded by

tsvxrg
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views20 pages

Message

The document describes the EternityNum library, which is designed to handle extremely large numbers up to 10↑↑2^1024. It includes various functions for checking, converting, and calculating with EternityNum values, as well as handling special cases like NaN and Infinity. The library provides a structured way to represent and manipulate these large numbers using a specific format.

Uploaded by

tsvxrg
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 20

--[[@FoundForces, modified by @Gamer_melon202

Creator:
Name: EternityNum (bignum but huge)
Description: A library to handle numbers upto 10↑↑2^1024
(https://googology.fandom.com/wiki/Arrow_notation)

List of functions below.


]]

--// Config
local expl = 1e10 -- exponent limit
local ldown = math.log10(expl) -- val for layer down
local msd = 100 -- max sig digits
local AllowOverflow = false -- if this is true functions like to scientific will go
to some other short function if input too large
local SuffixLimit = "1e3E9" -- Value when short() doesnt return suffix anymore
local DefaultDigits = 2 -- Amount of digits on short functions (-1 is all digits)

--[[
EN: A valid EternityNum Table
val: Any valid input that can be converted to an EternityNum Table

FUNCTIONS:
--// CHECK
EN.IsNan(EN): boolean -> returns if the given value is NAN or not
EN.IsInf(EN): boolean -> returns if the given value is INF or not
EN.IsZero(EN): boolean -> returns if the given value is 0 or not

--// CONVERT
EN.new(Sign, Layer, Exp): EN -> Directy create a new EternityNum Table :->:
Sign * (10^^Layer)^Exp
EN.fromNumber(number): EN -> Converts a number into an EternityNum Table
EN.fromString(string): EN -> Converts a string into an EternityNum Table
EN.fromScientific(string): EN -> Converts "XeY" into an EternityNum Table
EN.fromDefaultStringFormat(string): EN -> Converts "X;Y" into an EternityNum
Table
EN.convert(val): EN -> Converts any valid input to an EternityNum Table

EN.toNumber(EN): number -> Converts a EternityNum Table to an number


EN.toString(EN): string -> Converts a EternityNum Table to an string ("X;Y")
EN.toScientific(val): string -> Converts a value to an string ("XeY")
EN.toLayerNotation(val, digits): string -> Converts a value to an string
("E(x)y")
EN.toSuffix(val): string -> Converts a value to an suffix
EN.short(val, digits): string -> Converts a value to an displayable string

--// BOOLEAN
EN.eq(val1, val2): bool -> returns if val1 equals val2 (==)
EN.le(val1, val2): bool -> returns if val1 is less then val2 (<)
EN.me(val1, val2): bool -> returns if val1 is more then val2 (>)
EN.leeq(val1, val2): bool -> returns if val1 is less or equal then val2 (<=)
EN.meeq(val1, val2): bool -> returns if val1 is more or equal then val2 (>=)
EN.bewteen(val, min, max): bool -> returns if val is between min and max

--// S CALCS
EN.abs(val): EN -> returns the absolute value of val
EN.neg(val): EN -> returns the negated value of val (-val)
EN.recip(val): EN -> returns the reciprocal of val (1/val)
EN.log10(val): EN -> returns the logarithm base 10 of val
EN.abslog10(val): EN -> returns the logarithm base 10 of the absolute value
of val :->: log10(abs(val))
EN.exp(val): EN -> returns e^val
EN.pow10(val): EN -> returns 10^val
EN.sqrt(val): EN -> returns the square root of val
EN.gamma(val): EN -> returns (val - 1)!
EN.fact(val): EN -> returns val!
EN.correct(EN): EN -> error corrects an eternitynum (INTERNAL ONLY)

--// USE FOR LEADERBOARDS


EN.lbencode(val): number -> returns a number that can be stored in
ordereddatastore
EN.lbdecode(number): EN -> converts a lbecoded number back to an EternityNum
Table

--// BIN CALCS


EN.add(val1, val2): EN -> returns val1 + val2
EN.sub(val1, val2): EN -> returns val1 - val2
EN.mul(val1, val2): EN -> returns val1 * val2
EN.div(val1, val2): EN -> returns val1 / val2
EN.pow(val1, val2): EN -> returns val1 ^ val2
EN.log(val, base): EN -> returns logarithm of val, if base is nil it will
return log(val) (natural logarithm)
EN.root(val1, val2): EN -> returns val2'th root of val1
EN.rand(min, max): EN -> returns a random number between min and max
EN.exporand(min, max): EN -> returns a random number between min and max
EN.cmp(val1, val2): number ->
returns 0 if val1 == val2
returns 1 if val1 > val2
returns -1 if val1 < val2
EN.cmpAbs(EN1, EN2): number -> returns cmp(abs(EN1),abs(EN2))
EN.maxAbs(val1, val2): EN -> returns the max(abs(val1), abs(val2))
]]

-----------
local C = {0.99999999999980993, 676.5203681218851, -
1259.1392167224028,771.32342877765313, -176.61502916214059, 12.507343278686905, -
0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7}

function F_Gamma(n) : number -- (x-1)!


if n > 171.6236 then return 1.8e308 end --// Point where Gamma(x) will return
INF

if (n > 0.5) then


n -= 1
local x = C[1]

for i=1, 7 do
x += C[i + 1] / (n + i)
end

local t = n + 7.5
return x * t ^ (n + 0.5 - 36) * math.exp(-t) * t ^ 36 *
2.50662827463100050241576528
end
return 3.141592653589793238 / (math.sin(3.141592653589793238 * n) * F_Gamma(1
- n))
end
-----------

--// Constants
local tau = 6.2831853071795864769252842 --2*pi
local EXPN1 = 0.36787944117144232159553 --exp(-1)
local OMEGA = 0.56714329040978387299997 --W(1, 0)

function f_Lambertw(z) -- Lambertw function

local tol = 1e-10


local w, wn = nil

if z > 1.79e308 then return z end


if z == 0 then return z end
if z == 1 then return OMEGA end

if z < 10 then
w = 0
else
w = math.log(z)-math.log(math.log(z))
end

for i=1, 100 do


wn = (z * math.exp(-w) + w * w) / (w + 1)
if math.abs(wn - w) < tol * math.abs(wn) then
return wn
else
w = wn
end
end

error('Failed to itterate z.... at function: f_lambertw')


end

--// Start of EternityNum


-----------------------------------------------------------------------------------
-----------------------------
type EN = {Sign : number, Layer : number, Exp : number}
type BN = {Mantissa : number, Exp : number}
local EN = {}
-----------

function Cnew(Sign: number, Layer: number, Exp: number) : EN


return {Sign=Sign, Layer=Layer, Exp=Exp}
end

local ZERO: EN = Cnew(0, 0, 0)


local ONE: EN = Cnew(1, 0, 1)
local NaN: EN = Cnew(1, -1, 1)
local Inf: EN = Cnew(1, math.huge, 1)

local DefaultReturn = ZERO

function EN.IsNaN(Value: EN) : boolean


return Value.Sign == NaN.Sign and Value.Layer == NaN.Layer and Value.Exp ==
NaN.Exp
end

function EN.IsInf(Value: EN) : boolean


return Value.Layer == math.huge or Value.Exp == math.huge
end

function EN.IsZero(Value: EN) : boolean


return Value.Sign == 0 or (Value.Exp == 0 and Value.Layer == 0)
end

function EN.correct(EtNum: EN): EN --// Corrects a EtNum


if EN.IsNaN(EtNum) then return NaN end
if EN.IsInf(EtNum) then return Inf end
if EN.IsZero(EtNum) then return ZERO end
local Sign = EtNum.Sign
local Layers = EtNum.Layer
local Exp = EtNum.Exp

if Layers == 0 and Exp < 0 then


Exp =- Exp
Sign =- Sign
end

if Layers == 0 and Exp < 1e-10 then


Layers += 1
Exp = math.log10(Exp)
return Cnew(Sign, Layers, Exp)
end

local absExp = math.abs(Exp)


local signExp = math.sign(Exp)

if absExp >= expl then


Layers += 1
Exp = signExp * math.log10(absExp)
return Cnew(Sign, Layers, Exp)
else

while absExp < ldown and Layers > 0 do


Layers -= 1
if Layers == 0 then
Exp = math.pow(10, Exp)
else
Exp = signExp*math.pow(10, absExp)
absExp = math.abs(Exp)
signExp = math.sign(Exp)
end
end
if Layers == 0 then

if Exp < 0 then


Exp =- Exp
Sign =- Sign
end

elseif Exp == 0 then


Sign = 0
end

end

return Cnew(Sign, Layers, Exp)


end

function EN.new(Sign: number, Layer: number, Exp: number) : EN


return EN.correct({Sign=Sign, Layer=Layer, Exp=Exp} )
end

function EN.fromNumber(Value: number): EN --// Convert a number to EtNum


local num = {}
num.Sign = math.sign(Value)
num.Layer = 0
num.Exp = math.abs(Value)
return EN.correct(num)
end

function EN.fromScientific(Value: string): EN --// Convert from "XeY" to EtNum


local slice = Value:split("e")

local Mantissa = tonumber(slice[1])


local Exp = tonumber(slice[2])
local Sign = math.sign(Mantissa)

--// Normalise Mantissa \\--


local Overflow = math.floor(math.log10(Mantissa))
if Overflow > 0 then
Mantissa /= 10 ^ Overflow
Exp += Overflow
end
-----------------------------

if Exp == 0 then return EN.new(math.sign(Mantissa), 0, Mantissa) end --//


x*10^0 (so just return x)
if Mantissa == 0 then return ZERO end --// return 0

if Mantissa < 0 then Mantissa =- Mantissa end

if Exp < 0 then


if Exp < -100 then return ZERO end
local Exp2 = math.log10(Mantissa) + Exp
return EN.correct(EN.new(Sign, 1,Exp2))
end

local Exp2 = math.log10(Mantissa) + Exp


local Layers = 1
if Exp2 > expl then
Exp2 = math.log10(Exp2)
Layers += 1
end

return EN.correct(EN.new(Sign, Layers, Exp2))


end

function EN.fromDefaultStringFormat(Value: string) : EN --// Convert "X;Y" to EtNum


local slice = Value:split(";")
local Sign = math.sign(tonumber(slice[1]))
if Sign == 0 then Sign = 1 end
local Layers = math.abs(tonumber(slice[1]))
local Exp = tonumber(slice[2])
return EN.correct(EN.new(Sign, Layers, Exp))
end

function EN.fromString(Value: string)


if Value:find("e") and not Value:find(";") then -- Assuming its scientific
notation
return EN.fromScientific(Value)
elseif Value:find(";") then -- String representation
return EN.fromDefaultStringFormat(Value)
end

if Value == "NaN" then return NaN end


if Value == "Inf" then return Inf end
if Value == "" then return DefaultReturn end

return EN.fromNumber(tonumber(Value))
end

function EN.toString(Value: EN) : string


if EN.IsNaN(Value) then return "NaN" end
if EN.IsInf(Value) then return "Inf" end
return Value.Layer .. ";" .. Value.Exp
end

function EN.convert(Input) : EN --// Convert any valid type to EternityNum


if typeof(Input) == "number" then
return EN.fromNumber(Input)
elseif typeof(Input) == "string" then
return EN.fromString(Input)
elseif typeof(Input) == "table" then
if #Input == 2 then -- Its a BigNum (Adding this because if people are
updating for "BigNum")
local String = Input[1] .. "e" .. Input[2]
return EN.fromScientific(String)
elseif #Input == 3 then
return EN.correct(EN.new(Input[1], Input[2], Input[3]))
elseif Input.Sign then
return EN.correct(EN.new(Input.Sign, Input.Layer, Input.Exp))
end
end
warn("Returning DefaultReturn at EN.Convert(): Invalid input!")
return DefaultReturn
end
function EN.toNumber(Value: EN) : number --// Convert a EtNum to an number

if Value.Layer > 1 then


if math.sign(Value.Exp) == -1 then
return Value.Sign * 0
end
return Value.Sign * 1.8e308
end

if Value.Layer == 0 then
return Value.Sign * Value.Exp
elseif Value.Layer == 1 then
return Value.Sign * 10 ^ Value.Exp
end

return math.log10(-1)
end

function EN.abs(Value) : EN
Value = EN.convert(Value)

if Value.Sign == 0 then
return ZERO
end
return EN.new(1, Value.Layer, Value.Exp)
end

function EN.maxAbs(Value, Value2)


Value = EN.convert(Value)
Value2 = EN.convert(Value2)
if EN.cmpAbs(Value, Value2) < 0 then return Value2 end
return Value
end

function EN.neg(Value): EN --// Negate a EtNum


Value = EN.convert(Value)
return EN.new(-Value.Sign, Value.Layer, Value.Exp)
end

function EN.cmpAbs(Value: EN, Value2: EN) : number


local layera = nil
if Value.Exp > 0 then
layera = Value.Layer
else
layera =- Value.Layer
end

local layerb = nil


if Value2.Exp > 0 then
layerb = Value2.Layer
else
layerb =- Value2.Layer
end

if layera > layerb then return 1 end


if layera < layerb then return -1 end
if Value.Exp > Value2.Exp then return 1 end
if Value.Exp < Value2.Exp then return -1 end

return 0
end

function EN.cmp(Value: EN, Value2: EN) : number


if Value.Sign > Value2.Sign then return 1 end
if Value.Sign < Value2.Sign then return -1 end
return Value.Sign * EN.cmpAbs(Value, Value2)
end

function EN.le(Value, Value2) : boolean --// <


Value = EN.convert(Value)
Value2 = EN.convert(Value2)
return EN.cmp(Value, Value2) == -1
end

function EN.me(Value, Value2) : boolean --// >


Value = EN.convert(Value)
Value2 = EN.convert(Value2)
return EN.cmp(Value, Value2) == 1
end

function EN.eq(Value, Value2) : boolean --// ==


Value = EN.convert(Value)
Value2 = EN.convert(Value2)
return EN.cmp(Value, Value2) == 0
end

function EN.leeq(Value, Value2) : boolean --// ==


Value = EN.convert(Value)
Value2 = EN.convert(Value2)
return not (EN.cmp(Value, Value2) == 1)
end

function EN.meeq(Value, Value2) : boolean --// ==


Value = EN.convert(Value)
Value2 = EN.convert(Value2)
return not (EN.cmp(Value, Value2) == -1 )
end

function EN.recip(Value) : EN
Value = EN.convert(Value)
if Value.Exp == 0 then return NaN end

if Value.Layer == 0 then
return EN.new(Value.Sign, 0, 1/Value.Exp)
end

return EN.new(Value.Sign, Value.Layer, -Value.Exp)


end

function baseLog(Value, Base) : EN


Value = EN.convert(Value)
Base = EN.convert(Base)

if Value.Sign <= 0 or Base.Sign <= 0 then return NaN end


if EN.IsNaN(Base) or EN.IsNaN(Value) then
return NaN
end

if Value.Layer == 0 and Base.Layer == 0 then


return EN.new(Value.Sign, 0, math.log(Value.Exp) / math.log(Base.Exp))
end

return EN.div(EN.log10(Value), EN.log10(Base))


end

function EN.log(Value, Base) : EN --// Log of x


if Base then
return baseLog(Value, Base)
end

Value = EN.convert(Value)

if Value.Sign <= 0 then return NaN end

if Value.Layer == 0 then
-- log(10^x) = x*log(10)
return EN.new(Value.Sign, 0, math.log10(Value.Exp) * 2.302585092994046)
elseif Value.Layer == 1 then
--// so we have this for x*10^y, since log(x) = log10(x) * log(10) we
can do exactly that!
return EN.new(math.sign(Value.Exp), 0, math.abs(Value.Exp) *
2.302585092994046)
elseif Value.Layer == 2 then
--// 10^(x*10^y), turns out you can just take the log10 and then add
log10(log(10)) to the exponent
return EN.new(math.sign(Value.Exp), 1, math.abs(Value.Exp) +
0.36221568869946325)
end
--// log(x) ~ log10(x) at this point so we just return the log10

return EN.new(math.sign(Value.Exp), Value.Layer-1, math.abs(Value.Exp))


end

function EN.log10(Value) : EN --// log10(x)


Value = EN.convert(Value)

if Value.Sign <= 0 then return NaN end

if Value.Layer > 0 then


return EN.new(math.sign(Value.Exp), Value.Layer - 1,
math.abs(Value.Exp))
end

return EN.new(Value.Sign, 0 , math.log10(Value.Exp))


end

function EN.exp(Value) : EN --// e^x


Value = EN.convert(Value)

if Value.Layer == 0 and Value.Exp <= 709.7 then


return EN.fromNumber(math.exp(Value.Sign * Value.Exp))
elseif Value.Layer == 0 then
return EN.new(1, 1, Value.Sign * math.log10(2.718281828459045) *
Value.Exp)
elseif Value.Layer == 1 then
return EN.new(1, 2, Value.Sign * (math.log10(0.4342944819032518) +
Value.Exp))
else
return EN.new(1, Value.Layer + 1, Value.Sign * Value.Exp)
end
end

function EN.add(Value, Value2) : EN


Value = EN.convert(Value)
Value2 = EN.convert(Value2)
if EN.IsInf(Value) or EN.IsInf(Value2) then return Inf end
if EN.IsZero(Value) then return Value2 end
if EN.IsZero(Value2) then return Value end

if Value.Sign == -Value2.Sign and Value.Layer == Value2.Layer and Value.Exp


== Value2.Exp then
return ZERO
end

local a,b

if Value.Layer >= 2 or Value2.Layer >=2 then


return EN.maxAbs(Value, Value2)
end

if EN.cmpAbs(Value, Value2) > 0 then


a = Value
b = Value2
else
a = Value2
b = Value
end

if a.Layer == 0 and b.Layer == 0 then


return EN.fromNumber(a.Sign * a.Exp + b.Sign * b.Exp)
end

local layera = a.Layer * math.sign(a.Exp)

local layerb = b.Layer * math.sign(b.Exp)

if layera - layerb >= 2 then return a end

if layera == 0 and layerb == -1 then


if math.abs(b.Exp - math.log10(a.Exp)) > msd then
return a
else
local magdif = 10 ^ (math.log10(a.Exp) - b.Exp)
local Mantissa = b.Sign + a.Sign * magdif
return EN.new(math.sign(Mantissa), 1, b.Exp +
math.log10(math.abs(Mantissa)))
end
end

if layera == 1 and layerb == 0 then


if math.abs(a.Exp - math.log10(b.Exp)) > msd then return a end
local magdif = 10 ^ (a.Exp-math.log10(b.Exp))
local Mantissa = b.Sign + a.Sign * magdif
return EN.new(math.sign(Mantissa), 1, math.log10(b.Exp) +
math.log10(math.abs(Mantissa)))
end

if math.abs(a.Exp - b.Exp) > msd then return a end

local magdif = 10 ^ (a.Exp - b.Exp)


local Mantissa = b.Sign + a.Sign * magdif
return EN.new(math.sign(Mantissa), 1,b.Exp + math.log10(math.abs(Mantissa)))
end

function EN.sub(Value, Value2) : EN


Value = EN.convert(Value)
Value2 = EN.convert(Value2)
return EN.add(Value, EN.neg(Value2))
end

function EN.bnumtostr(Value: EN) : string


if Value.Layer > 2 then if AllowOverflow then return "" end return "Inf" end
if Value.Layer == 2 and Value.Exp > 308 then return "Inf" end
if EN.IsZero(Value) then return "0e0" end

if Value.Layer == 0 then
local Mantissa = (Value.Exp / 10^ math.floor(math.log10(Value.Exp))) *
Value.Sign
return Mantissa .. "e" .. math.floor(math.log10(Value.Exp))
elseif Value.Layer == 1 then
local Mantissa = (10 ^ (Value.Exp - math.floor(Value.Exp))) *
Value.Sign
return Mantissa .. "e" .. math.floor(Value.Exp)
end

local Exp = 10 ^ Value.Exp


local Mantissa = (10 ^ (Exp - math.floor(Exp)))* Value.Sign
return Mantissa .. "e" .. math.floor(Exp)
end

function EN.mul(Value, Value2) : EN


Value = EN.convert(Value)
Value2 = EN.convert(Value2)

if EN.IsInf(Value) or EN.IsInf(Value2) then


return Inf
end

if EN.IsZero(Value) or EN.IsZero(Value2) then


return ZERO
end

if Value.Layer == Value2.Layer and Value.Exp == -Value2.Exp then


return EN.new(Value.Sign * Value2.Sign, 0, 1)
end

local a: EN,b: EN
if (Value.Layer > Value2.Layer) or (Value.Layer == Value2.Layer and
math.abs(Value.Exp) > math.abs(Value2.Exp)) then
a = Value
b = Value2
else
a = Value2
b = Value
end

if a.Layer == 0 and b.Layer == 0 then


return EN.fromNumber(a.Sign * b.Sign * a.Exp * b.Exp)
end
if a.Layer >= 3 or (a.Layer - b.Layer >= 2) then
return EN.new(a.Sign * b.Sign, a.Layer, a.Exp)
end
if a.Layer == 1 and b.Layer == 0 then
return EN.new(a.Sign * b.Sign, 1, a.Exp + math.log10(b.Exp))
end
if a.Layer == 1 and b.Layer == 1 then
return EN.new(a.Sign * b.Sign, 1, a.Exp + b.Exp)
end

if (a.Layer == 2 and b.Layer == 1) or (a.Layer == 2 and b.Layer == 2) then


local temp = EN.new(math.sign(b.Exp), b.Layer - 1, math.abs(b.Exp))
local nmag = EN.add(EN.new(math.sign(a.Exp), a.Layer-1,
math.abs(a.Exp)), temp)
return EN.new(a.Sign * b.Sign, nmag.Layer + 1, nmag.Sign * nmag.Exp)
end

return NaN
end

function EN.div(Value, Value2) : EN


Value = EN.convert(Value)
Value2 = EN.convert(Value2)
return EN.mul(Value, EN.recip(Value2))
end

function EN.abslog10(Value) : EN
Value = EN.convert(Value)
if EN.IsZero(Value) then return NaN end

if Value.Layer > 0 then


return EN.new(math.sign(Value.Exp), Value.Layer - 1,
math.abs(Value.Exp))
end

return EN.new(1, 0, math.log10(math.abs(Value.Exp)))


end

function EN.pow10(Value) : EN

Value = EN.convert(Value)

if EN.IsInf(Value) then return Inf end


if Value.Layer == 0 then
local nmag = 10 ^ (Value.Sign * Value.Exp)
if nmag < 1.8e308 and math.abs(nmag) > 0.1 then
return EN.new(1, 0, nmag)
else
if Value.Sign == 0 then return ONE end
Value = EN.new(Value.Sign, Value.Layer + 1,
math.log10(Value.Exp))
end
end

if Value.Sign > 0 and Value.Exp > 0 then

return EN.new(Value.Sign, Value.Layer + 1, Value.Exp)


end
if Value.Sign < 0 and Value.Exp > 0 then
return EN.new(-Value.Sign, Value.Layer + 1, -Value.Exp)
end

return ONE
end

function EN.pow(Value, Value2) : EN


Value = EN.convert(Value)
Value2 = EN.convert(Value2)
if EN.IsZero(Value) then -- 0^x = 0
return ZERO
end

if Value.Sign == 1 and Value.Layer == 0 and Value.Exp == 1 then -- 1^x = 1


return ONE
end
if EN.IsZero(Value2) then -- x^0 = 1
return ONE
end
if Value2.Sign == 1 and Value2.Layer == 0 and Value2.Exp == 1 then -- 1^x = 1
return Value
end

local calc = EN.pow10(EN.mul(EN.abslog10(Value), Value2))


if Value.Sign == -1 and EN.toNumber(Value2) % 2 == 1 then
return EN.neg(calc)
elseif Value.Sign == -1 and EN.toNumber(Value2) < 1e20 then
local component = EN.fromNumber(math.cos(EN.toNumber(Value2) *
math.pi))
return EN.mul(calc, component)
end

return calc
end

-----------------------------------------------------------------------------------
---

local Sets = {"k","M","B"}


local FirstOnes = {"", "U","D","T","Qd","Qn","Sx","Sp","Oc","No"}
local SecondOnes = {"", "De","Vt","Tg","qg","Qg","sg","Sg","Og","Ng"}
local ThirdOnes = {"", "Ce", "Du","Tr","Qa","Qi","Se","Si","Ot","Ni"}
local MultOnes = {
"", "Mi","Mc","Na","Pi","Fm","At","Zp","Yc", "Xo", "Ve", "Me",
"Due", "Tre", "Te", "Pt", "He", "Hp", "Oct", "En", "Ic", "Mei",
"Dui", "Tri", "Teti", "Pti", "Hei", "Hp", "Oci", "Eni", "Tra","TeC",
"MTc","DTc","TrTc","TeTc","PeTc","HTc","HpT","OcT","EnT","TetC","MTetc",
"DTetc","TrTetc","TeTetc","PeTetc","HTetc","HpTetc","OcTetc","EnTetc","PcT",
"MPcT","DPcT","TPCt","TePCt","PePCt","HePCt","HpPct","OcPct","EnPct","HCt",
"MHcT","DHcT","THCt","TeHCt","PeHCt","HeHCt","HpHct","OcHct","EnHct","HpCt",
"MHpcT","DHpcT","THpCt","TeHpCt","PeHpCt","HeHpCt","HpHpct","OcHpct","EnHpct"
,
"OCt","MOcT","DOcT","TOCt","TeOCt","PeOCt","HeOCt","HpOct","OcOct","EnOct","E
nt","MEnT",
"DEnT","TEnt","TeEnt","PeEnt","HeEnt","HpEnt","OcEnt","EnEnt","Hect",
"MeHect","DueHect",
"TreHect","TeHect","PtHect","HeHect","HpHect","OciHect","EniHect","TraHect","
TeCHect","MTcHect"}

function CutDigits(Value, Digits)


if Digits < 0 then return Value end
return math.floor(Value * 10 ^ Digits) / 10 ^ Digits
end

function EN.toSuffix(Value: EN, Digits: number) : string

Digits = Digits or DefaultDigits


local BigNum = EN.toScientific(Value):split("e")
local Mantissa = BigNum[1]
local Exponent = BigNum[2]
local Modulus3 = math.fmod(Exponent, 3)
Exponent = math.floor(Exponent / 3) - 1

if Exponent <= -1 then return CutDigits(BigNum[1] * 10 ^ BigNum[2], Digits)


end

if Exponent < 3 then


return CutDigits(Mantissa * 10 ^ Modulus3, Digits) .. Sets[Exponent +
1]
end

local OutString = ""

local function SuffixPartOne(n)

local Hundreds = math.floor(n / 100)


n = math.fmod(n, 100)
local Tens = math.floor(n / 10)
n = math.fmod(n, 10)
local Ones = math.floor(n / 1)

OutString = OutString .. FirstOnes[Ones + 1]


OutString = OutString .. SecondOnes[Tens + 1]
OutString = OutString .. ThirdOnes[Hundreds + 1]

end

local function SuffixPartTwo(n)


if n > 0 then n += 1 end
if n > 1000 then n = math.fmod(n, 1000) end
SuffixPartOne(n)
end

if Exponent < 1000 then


SuffixPartOne(Exponent)
return CutDigits(Mantissa * 10 ^ Modulus3, Digits) .. OutString
end

for i=math.floor(math.log10(Exponent) / 3), 0, -1 do


if Exponent >= 10^(i*3) then
SuffixPartTwo(math.floor(Exponent / 10 ^ (i * 3)) - 1)
OutString = OutString .. MultOnes[i + 1]
Exponent = math.fmod(Exponent, 10 ^ (i * 3))
end
end

return CutDigits(Mantissa * 10 ^ Modulus3, Digits) .. OutString


end

function EN.between(Val, x, y) : boolean


Val = EN.convert(Val)
x = EN.convert(x)
y = EN.convert(y)
return EN.me(Val, x) and EN.le(Val, y)
end

function EN.toLayerNotation(Value, Digits : number) : string


Value = EN.convert(Value)
Digits = Digits or DefaultDigits

if EN.between(Value, ZERO, ONE) then


return "1 / " .. EN.short(EN.div(ONE, Value))
end

if Value.Sign == 1 then

if Value.Exp < 0 then


return 'E(' .. Value.Layer .. '-' .. ')' ..
CutDigits(math.abs(Value.Exp), Digits)
end

return 'E(' .. Value.Layer .. ')' .. CutDigits(Value.Exp, Digits)


end

if Value.Sign == 0 then
return 'E(0)0'
end

return EN.toLayerNotation(EN.abs(Value), Digits)


end

function EN.toExpantaNotation(Value, Digits : number) : string


Value = EN.convert(Value)
Digits = Digits or DefaultDigits

if EN.between(Value, ZERO, ONE) then


return "1 / " .. EN.short(EN.div(ONE, Value))
end

if Value.Sign == 1 and Value.Sign ~= "-inf" then

if Value.Exp < 0 then


return CutDigits(math.abs(Value.Exp),
Digits)..'F'..Value.Layer.."<"
end

return Value.Layer .. 'F' .. CutDigits(Value.Exp, Digits)


end

if Value.Sign == 0 then
return 'F0'
elseif Value.Sign == "-inf"then
return "-∞"
end

return EN.toLayerNotation(EN.abs(Value), Digits)


end

function EN.short(Value, Digits) : string


Value = EN.convert(Value)
if EN.le(Value, SuffixLimit) then
return EN.toSuffix(Value, Digits)
end
return EN.toLayerNotation(Value, Digits)
end

function EN.root(Value, Value2) : EN


Value = EN.convert(Value)
Value2 = EN.convert(Value2)
return EN.pow(Value, EN.recip(Value2))
end

function EN.sqrt(Value) : EN
Value = EN.convert(Value)
return EN.root(Value, 2)
end

function EN.gamma(Value) : EN
Value = EN.convert(Value)

if EN.leeq(Value, ZERO) then return NaN end


if Value.Exp < 0 then return EN.recip(Value) end

if Value.Layer == 0 then
if EN.le(Value, {1, 0, 24}) then
return EN.fromNumber(F_Gamma(Value.Sign * Value.Exp))
end

local t = Value.Exp - 1
local l = 0.9189385332046727
l = (l + ((t + 0.5) * math.log(t)))
l = l - t
local n2 = t * t
local np = t
local lm = 12 * np
local adj = 1 / lm
local l2 = l + adj

if (l2 == l) then return EN.exp(l) end

l = l2
np = np * n2
lm = 360 * np
adj = 1 / lm
l2 = l - adj

if l2 == l then return EN.exp(l) end

l = l2
np = np * n2
lm = 1260 * np
local lt = 1 / lm
l = l + lt
np = np * n2
lm = 1680 * np
lt = 1 / lm
l = l - lt

return EN.exp(l)

elseif Value.Layer == 1 then


return EN.exp(EN.mul(Value, EN.sub(EN.log(Value), 1)))
end

return EN.exp(Value)
end

function EN.fact(Value) : EN
Value = EN.convert(Value)
return EN.gamma(EN.add(Value, 1))
end

function EN.rand(min, max) : EN


local seed = math.random()
local even = EN.sub(max, min)
even = EN.mul(even, seed)
return EN.add(even, min)
end

function EN.exporand(min, max) : EN


local min, max = EN.convert(min), EN.convert(max)
local sign, sign2 = min.Sign, max.Sign
local min = EN.mul(EN.exp(EN.abs(min)), sign)
local max = EN.mul(EN.exp(EN.abs(max)), sign2)
return EN.exp(EN.rand(min, max))
end

function EN.lbencode(enum) : number -- encode cool!


enum = EN.convert(enum)
if EN.eq(enum, 1) then return 1 end
local mode = 0
if enum.Sign == -1 and enum.Layer > 9999 and math.sign(enum.Exp) == 1 then
mode = 0
elseif enum.Sign == -1 and enum.Layer < 9999 and math.sign(enum.Exp) == 1
then
mode = 1
elseif enum.Sign == -1 and enum.Layer > 9999 and math.sign(enum.Exp) == -1
then
mode = 2
elseif enum.Sign == -1 and enum.Layer < 9999 and math.sign(enum.Exp) == -1
then
mode = 3
elseif enum.Sign == 0 then
return 4E18
elseif enum.Sign == 1 and enum.Layer < 9999 and math.sign(enum.Exp) == -1
then
mode = 5
elseif enum.Sign == 1 and enum.Layer > 9999 and math.sign(enum.Exp) == -1
then
mode = 6
elseif enum.Sign == 1 and enum.Layer < 9999 and math.sign(enum.Exp) == 1 then
mode = 7
elseif enum.Sign == 1 and enum.Layer > 9999 and math.sign(enum.Exp) == 1 then
mode = 8
end

local VAL = mode*1E18


if mode == 8 then
VAL += ((math.log10(enum.Layer + (math.log10(enum.Exp) / 10))) *
3.2440674117208e+15)
elseif mode == 7 then
VAL += (enum.Layer * 1e14)
VAL += (math.log10(enum.Exp) * 1e13)
elseif mode == 6 then
VAL += 1e18
VAL -= ((math.log10(enum.Layer + (math.log10(math.abs(enum.Exp)) /
10))) * 3.2440674117208e+15)
elseif mode == 5 then
VAL += (enum.Layer * 1e14) + 1e14
VAL -= (math.log10(math.abs(enum.Exp)) * 1e13)
elseif mode == 3 then
local VOFFSET = 0
VAL += (enum.Layer * 1e14) + 1e14
VAL -= (math.log10(math.abs(enum.Exp)) * 1e13)
VOFFSET = (1e18 - VOFFSET)
VAL += VOFFSET
elseif mode == 2 then
local VOFFSET = 0
VAL += 1e18
VAL -= ((math.log10(enum.Layer + (math.log10(math.abs(enum.Exp)) /
10))) * 3.2440674117208e+15)
VOFFSET = (1e18 - VOFFSET)
VAL += VOFFSET
elseif mode == 1 then
local VOFFSET = 0
VAL += (enum.Layer * 1e14)
VAL += (math.log10(enum.Exp) * 1e13)
VOFFSET = (1e18 - VOFFSET)
VAL += VOFFSET
elseif mode == 0 then
local VOFFSET = ((math.log10(enum.Layer + (math.log10(enum.Exp) / 10)))
* 3.2440674117208e+15)
VOFFSET = (1e18 - VOFFSET)
VAL += VOFFSET
end

return VAL
end
function EN.lbdecode(enum : number) : EN -- decodes numbers for extra spice
if enum == 2e18 then
return EN.new(-1, 0, 1)
elseif enum == 3e18 then
return EN.new(-1, 10000, -1)
elseif enum == 1e18 then
return EN.new(-1, 0, -1)
elseif enum == 6e18 then
return ONE
elseif enum == 7e18 then
return EN.new(1, 10000, 1)
elseif enum == 5e18 then
return EN.new(1, 10000, -1)
elseif enum == 1 then
return ONE
end

local mode = math.floor(enum / 1e18)


if mode == 4 then
return ZERO
end

if mode == 0 then
local v = enum
v = 1e18 - v
v /= 3.2440674117208e+15
v = 10 ^ v
local layers = math.floor(v)
local numbaa = 10 ^ (math.fmod(v, 1) * 10)
return EN.new(-1, layers, numbaa)

elseif mode == 8 then


local v = enum - 8e18
v /= 3.2440674117208e+15
v = 10 ^ v
local layers = math.floor(v)
local numbaa = 10 ^ (math.fmod(v, 1) * 10)
return EN.new(1, layers, numbaa)

elseif mode == 1 then


local v = enum - 1e18
v = 1e18-v
local layers = math.floor(v / 1E14)
local numbaa = 10 ^ (math.fmod(v, 1e14) / 1e13)
return EN.new(-1, layers, numbaa)

elseif mode == 7 then


local v = enum - 7e18
local layers = math.floor(v / 1E14)
local numbaa = 10 ^ (math.fmod(v, 1e14) / 1e13)
return EN.new(1, layers, numbaa)

elseif mode == 2 then


local v = enum - 2e18
v /= 3.2440674117208e+15
v = 10 ^ v
local layers = math.floor(v)
local e = 10 ^ (math.fmod(v,1) * 10)
return EN.new(-1, layers, -e)

elseif mode == 6 then


local v = enum - 6e18
v = (1e18 - v)
v /= 3.2440674117208e+15
v = 10 ^ v
local layers = math.floor(v)
local e = 10 ^ (math.fmod(v,1) * 10)
return EN.new(1, layers, -e)

elseif mode == 5 then


local v = enum - 5e18
local layers = math.floor((v) / 1E14)
local e = 10 ^ ((1e14 - math.fmod(v, 1e14)) / 1e13)
return EN.new(1, layers, -e)

elseif mode == 3 then


local v = enum - 3e18
v = (1e18 - v)
local layers = math.floor((v) / 1E14)
local e = 10 ^ ((1e14 - math.fmod(v, 1e14)) / 1e13)
return EN.new(-1, layers, -e)

end

return NaN
end

function EN.shift(Value, digits)


Value = EN.convert(Value)
if Value.Layer > 1 then return Value end
if digits > 20 then return Value end
local d = 10 ^ (Value.Exp - math.floor(Value.Exp))
d = math.floor(digits * 10^digits) / 10^digits
Value.Exp = math.floor(Value.Exp) + math.log10(d)
return Value
end

function EN.fromBigNum(int)
local bnum = require(game.ReplicatedStorage.BigNum)
int = bnum.bnumtostr(int)
int = string.split(int,"e")
local arg1 = tostring(int[1])
local arg2 = tostring(int[2])
local intr = arg1..";"..arg2
return intr
end

return EN

You might also like