Last active
June 25, 2018 06:26
-
-
Save Capital-EX/364f884e3140207ca0b2995aeca2329d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extends Reference | |
var digits = IntArray() | |
var negative = false | |
const scale = 1000 | |
const base = 1000 | |
func _init(size = 0): | |
while digits.size() < size: digits.append(0) | |
static func from_list(ds): | |
var x = new() | |
x.digits = IntArray(ds) | |
return x | |
static func _new(size = 0): return new(size) | |
func copy(): | |
var x = _new() | |
x.digits.append_array(self.digits) | |
return x | |
func plus(other): | |
var short | |
var long | |
if other.digits.size() > self.digits.size(): | |
short = self.digits | |
long = other.digits | |
else: | |
short = other.digits | |
long = self.digits | |
var sum = _new(long.size()) | |
for digit in range(short.size()): | |
var result = short[digit] + long[digit] + sum.digits[digit] | |
if result >= base: | |
sum.digits[digit] = result % base | |
sum.digits[digit + 1] = result / base | |
else: | |
sum.digits[digit] = result | |
if short.size() != long.size(): | |
for digit in range(short.size(), long.size()): | |
var result = sum.digits[digit] + long[digit] | |
if result >= base: | |
sum.digits[digit] = result % base | |
if digit + 1 >= sum.size(): | |
sum._append(result / base) | |
else: | |
sum.digits[digit + 1] = result / base | |
else: | |
sum.digits[digit] = result | |
return sum | |
func minus(other): | |
if self.gt(other): | |
return self.complement().plus(other).complement() | |
else: | |
var x = other._minus(self) | |
x.negative = true | |
return x | |
func times(other): | |
var x = self.digits | |
var y = other.digits | |
var product = _new(x.size() + y.size()) | |
for i in range(x.size()): | |
for j in range(y.size()): | |
var result = x[i] * y[j] + product.digits[i + j] | |
if result >= base: | |
product.digits[i + j] = result % base | |
product.digits[i + j + 1] += result / 1000 | |
else: | |
product.digits[i + j] = result | |
return product.trim().shift_1000() | |
func times_int(integer): | |
var product = _new(self.size() + int(log(integer) / log(base))) | |
for i in range(digits.size()): | |
var result = digits[i] * integer + product.digits[i] | |
if result >= base: | |
product.digits[i] = result % base | |
if product.size() < i + 2: | |
product._append(result / base) | |
else: | |
product.digits[i+1] = result / base | |
else: | |
product.digits[i] = result | |
return product | |
func shift_10(): | |
var shifted = _new() | |
shifted._append(digits[0] / 10) | |
for digit in range(1, digits.size()): | |
if digit != digits.size() - 1 or digits[digit] / 10 != 0: | |
shifted._append(digits[digit] / 10) | |
shifted.digits[digit - 1] += (digits[digit] % 10) * 100 | |
return shifted | |
func shift_100(): | |
var shifted = _new() | |
shifted._append(digits[0] / 100) | |
for digit in range(1, digits.size()): | |
if digit != digits.size() - 1 or digits[digit] / 100 != 0: | |
shifted._append(digits[digit] / 100) | |
shifted.digits[digit - 1] += (digits[digit] % 100) * 10 | |
return shifted | |
func shift_1000(): | |
var shifted = _new() | |
for digit in range(1, digits.size()): | |
shifted._append(digits[digit]) | |
return shifted | |
func shift_10000(): | |
var shifted = _new() | |
shifted._append(digits[1] / 10) | |
for digit in range(2, digits.size()): | |
if digit != digits.size() - 1 or digits[digit] / 10 != 0: | |
shifted._append(digits[digit] / 10) | |
shifted.digits[digit - 1] += (digits[digit] % 10) * 100 | |
return shifted | |
func comp(other): | |
if other.size() < digits.size(): | |
return 1 | |
elif other.size() > digits.size(): | |
return -1 | |
else: | |
for i in range(digits.size()): | |
if digits[i] != other.digits[i]: | |
if digits[i] > other.digits[i]: | |
return 1 | |
else: | |
return -1 | |
return 0 | |
# The complement of a number is formed | |
# By subtracting the "digit" from | |
# one less than the Radix (1000 => 999) | |
func complement(): | |
var complement = _new() | |
for digit in digits: | |
complement._append(999 - digit) | |
print(complement.digits) | |
return complement | |
func trim(): | |
var copy_from = digits.size() | |
for index in range(digits.size() - 1, 0, -1): | |
if digits[index] == 0: | |
copy_from -= 1 | |
else: | |
break | |
var trimmed = _new(copy_from) | |
for index in range(copy_from - 1, 0, -1): | |
trimmed.digits[index] = digits[index] | |
return trimmed | |
func gt(other): return self.comp(other) == 1 | |
func lt(other): return self.comp(other) == -1 | |
func eq(other): return self.comp(other) == 0 | |
func neq(other): return self.comp(other) != 0 | |
func leq(other): return self.comp(other) <= 0 | |
func geq(other): return self.comp(other) >= 0 | |
func size(): return self.digits.size() | |
func _append(val): digits.append(val) | |
func _minus(other): return complement().plus(other).complement() | |
func to_string(): | |
var string = ".%03d" % digits[0] | |
for digit in range(1, digits.size() - 1): | |
string = string.insert(0, ",%03d" % digits[digit]) | |
if negative: | |
string = string.insert(0, "-%d" % digits[digits.size() - 1]) | |
else: | |
string = string.insert(0, "%d" % digits[digits.size() - 1]) | |
return string |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment