Professional Documents
Culture Documents
Ac
Ac
# Big number class for use in idle / incremental games and other games that needs
very large numbers
# Can format large numbers using a variety of notation methods:
# AA notation like AA, AB, AC etc.
# Metric symbol notation k, m, G, T etc.
# Metric name notation kilo, mega, giga, tera etc.
# Long names like octo-vigin-tillion or millia-nongen-quin-vigin-tillion (based on
work by Landon Curt Noll)
# Scientic notation like 13e37 or 42e42
# Long strings like 4200000000 or 13370000000000000000000000000000
# Please note that this class has limited precision and does not fully support
negative exponents
const latin_ones = ["", "un", "duo", "tre", "quattuor", "quin", "sex", "septen",
"octo", "novem"]
const latin_tens = ["", "dec", "vigin", "trigin", "quadragin", "quinquagin",
"sexagin", "septuagin", "octogin", "nonagin"]
const latin_hundreds = ["", "cen", "duocen", "trecen", "quadringen", "quingen",
"sescen", "septingen", "octingen", "nongen"]
const latin_special = ["", "mi", "bi", "tri", "quadri", "quin", "sex", "sept",
"oct", "non"]
const MAX_MANTISSA =
999999999999999999999999999999999999999999999999999999999999999999999999999999999.0
const MANTISSA_PRECISSION = 0.0000001
func get_class():
return "Big"
func is_class(c):
return c == "Big"
func _sizeCheck(m):
if m > MAX_MANTISSA:
printerr("BIG ERROR: MANTISSA TOO LARGE, PLEASE USE EXPONENT OR
SCIENTIFIC NOTATION")
func plus(n):
n = _typeCheck(n)
_sizeCheck(n.mantissa)
var exp_diff = n.exponent - exponent
if exp_diff < 248:
var scaled_mantissa = n.mantissa * pow(10, exp_diff)
mantissa += scaled_mantissa
elif isLessThan(n):
mantissa = n.mantissa #when difference between values is big, throw
away small number
exponent = n.exponent
calculate(self)
return self
func minus(n):
n = _typeCheck(n)
_sizeCheck(n.mantissa)
var exp_diff = n.exponent - exponent #abs?
if exp_diff < 248:
var scaled_mantissa = n.mantissa * pow(10, exp_diff)
mantissa -= scaled_mantissa
elif isLessThan(n):
mantissa = -MANTISSA_PRECISSION
exponent = n.exponent
calculate(self)
return self
func multiply(n):
n = _typeCheck(n)
_sizeCheck(n.mantissa)
var new_exponent = n.exponent + exponent
var new_mantissa = n.mantissa * mantissa
while new_mantissa >= 10.0:
new_mantissa /= 10.0
new_exponent += 1
mantissa = new_mantissa
exponent = new_exponent
calculate(self)
return self
func divide(n):
n = _typeCheck(n)
_sizeCheck(n.mantissa)
if n.mantissa == 0:
printerr("BIG ERROR: DIVIDE BY ZERO OR LESS THAN " +
str(MANTISSA_PRECISSION))
return self
var new_exponent = exponent - n.exponent
var new_mantissa = mantissa / n.mantissa
while new_mantissa < 1.0 and new_mantissa > 0.0:
new_mantissa *= 10.0
new_exponent -= 1
mantissa = new_mantissa
exponent = new_exponent
calculate(self)
return self
func squareRoot():
if exponent % 2 == 0:
mantissa = sqrt(mantissa)
exponent = exponent/2 # warning-ignore:integer_division
else:
mantissa = sqrt(mantissa*10)
exponent = (exponent-1)/2 # warning-ignore:integer_division
calculate(self)
return self
func modulo(n):
n = _typeCheck(n)
_sizeCheck(n.mantissa)
var big = {"mantissa":mantissa, "exponent":exponent}
divide(n)
roundDown()
multiply(n)
minus(big)
mantissa = abs(mantissa)
return self
func calculate(big):
if big.mantissa >= 10.0 or big.mantissa < 1.0:
var diff = int(floor(log10(big.mantissa)))
if diff > -10 and diff < 248:
var div = pow(10, diff)
if div > MANTISSA_PRECISSION:
big.mantissa /= div
big.exponent += diff
while big.exponent < 0:
big.mantissa *= 0.1
big.exponent += 1
while big.mantissa >= 10.0:
big.mantissa *= 0.1
big.exponent += 1
if big.mantissa == 0:
big.mantissa = 0.0
big.exponent = 0
big.mantissa = stepify(big.mantissa, MANTISSA_PRECISSION)
pass
func isEqualTo(n):
n = _typeCheck(n)
calculate(n)
return n.exponent == exponent and is_equal_approx(n.mantissa, mantissa)
func isLargerThan(n):
return !isLessThanOrEqualTo(n)
func isLargerThanOrEqualTo(n):
return !isLessThan(n)
func isLessThan(n):
n = _typeCheck(n)
calculate(n)
if mantissa == 0 and (n.mantissa > MANTISSA_PRECISSION or mantissa <
MANTISSA_PRECISSION) and n.mantissa == 0:
return false
if exponent < n.exponent:
return true
elif exponent == n.exponent:
if mantissa < n.mantissa:
return true
else:
return false
else:
return false
func isLessThanOrEqualTo(n):
n = _typeCheck(n)
calculate(n)
if isLessThan(n):
return true
if n.exponent == exponent and is_equal_approx(n.mantissa, mantissa):
return true
return false
func roundDown():
if exponent == 0:
mantissa = floor(mantissa)
return self
else:
var precision = 1.0
for i in range(min(8, exponent)):
precision /= 10.0
if precision < MANTISSA_PRECISSION:
precision = MANTISSA_PRECISSION
mantissa = stepify(mantissa, precision)
return self
func log10(x):
return log(x) * 0.4342944819032518
func toString():
var mantissa_decimals = 0
if str(mantissa).find(".") >= 0:
mantissa_decimals = str(mantissa).split(".")[1].length()
if mantissa_decimals > exponent:
if exponent < 248:
return str(mantissa * pow(10, exponent))
else:
return toScientific()
else:
var mantissa_string = str(mantissa).replace(".", "")
for _i in range(exponent-mantissa_decimals):
mantissa_string += "0"
return mantissa_string
func toScientific():
return str(mantissa) + "e" + str(exponent)
func toShortScientific():
return str(stepify(mantissa, 0.1)) + "e" + str(exponent)
func toFloat():
return stepify(float(str(mantissa) + "e" + str(exponent)),0.01)
return result
return result
# warning-ignore:integer_division
func _latinPower(european_system):
if european_system:
return int(exponent / 3) / 2 # warning-ignore:integer_division
return int(exponent / 3) - 1 # warning-ignore:integer_division
func _latinPrefix(european_system):
var ones = _latinPower(european_system) % 10
var tens = int(_latinPower(european_system) / 10) % 10
var hundreds = int(_latinPower(european_system) / 100) % 10
var millias = int(_latinPower(european_system) / 1000) % 10
for _i in range(millias):
prefix = "millia" + other.reading_separator + prefix
return prefix.lstrip(other.reading_separator).rstrip(other.reading_separator)
func _tillionOrIllion(european_system):
if exponent < 6:
return ""
var powerKilo = _latinPower(european_system) % 1000
if powerKilo < 5 and powerKilo > 0 and _latinPower(european_system) < 1000:
return ""
if powerKilo >= 7 and powerKilo <= 10 or int(powerKilo / 10) % 10 == 1:
return "i"
return "ti"
func _llionOrLliard(european_system):
if exponent < 6:
return ""
if int(exponent/3) % 2 == 1 and european_system: # warning-
ignore:integer_division
return "lliard"
return "llion"
if not postfixes_metric_symbol.has(str(target)):
return toScientific()
else:
return toPrefix(no_decimals_on_small_values) + other.postfix_separator
+ postfixes_metric_symbol[str(target)]
func toMetricName(no_decimals_on_small_values = false):
var target = int(exponent / 3) # warning-ignore:integer_division
if not postfixes_metric_name.has(str(target)):
return toScientific()
else:
return toPrefix(no_decimals_on_small_values) + other.postfix_separator
+ postfixes_metric_name[str(target)]
# This is quite slow for very big numbers, but we save the result for next
similar target
if not postfixes_aa.has(str(target)):
var units = [0,0]
var m = 0
var u = 1
#print("UNIT " + str(target) + " NOT FOUND IN TABLE - GENERATING IT
INSTEAD")
while (m < target-5):
m += 1
units[u] += 1
if units[u] == alphabet_aa.size():
var found = false
for i in range(units.size()-1,-1,-1):
if not found and units[i] < alphabet_aa.size()-1:
units[i] += 1
found = true
units[u] = 0
if not found:
units.append(0)
u += 1
for i in range(units.size()):
units[i] = 0
for i in range(units.size()):
postfix = postfix + str(alphabet_aa[units[i]])
postfixes_aa[str(target)] = postfix
else:
postfix = postfixes_aa[str(target)]