Advertisement
Guest User

Untitled

a guest
Apr 21st, 2025
11
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
GDScript 22.02 KB | Source Code | 0 0
  1. # Meowing Cat's Big Number Library for Godot Engine
  2. # Copyright (C) 2024, Oğuzhan Eroğlu <[email protected]> (https://oguzhaneroglu.com)
  3. # Licensed under MIT License (https://opensource.org/licenses/MIT)
  4. # See LICENSE file for more information
  5.  
  6. class_name BigNumber extends RefCounted
  7.  
  8. # ALl atomic scalar operations are done with 30-bit integers
  9. # They never exceed the native integer limit (2^63 - 1)
  10. # So that's why we can use ATOMIC_BITS = 30 at maximum
  11. const ATOMIC_BITS := 30
  12. const ATOMIC_BITS_F := float(ATOMIC_BITS)
  13. const ATOMIC_MAX := int(pow(2, ATOMIC_BITS)) # Godot's Native Max: 9223372036854775807
  14. const ATOMIC_MAX_MINUS_ONE := ATOMIC_MAX - 1
  15.  
  16. const BASE_DIGITS = "0123456789abcdefghijklmnopqrstuvwxyz"
  17. const ALPHABET = "abcdefghijklmnopqrstuvwxyz"
  18.  
  19. const IS_VERBOSE := false
  20.  
  21. static var ZERO := BigNumber.from_uint(0)
  22. static var ONE := BigNumber.from_uint(1)
  23. static var TWO := BigNumber.from_uint(2)
  24. static var THREE := BigNumber.from_uint(3)
  25. static var FOUR := BigNumber.from_uint(4)
  26.  
  27. var value: PackedInt64Array = []
  28. var is_negative: bool = false
  29. var string: String: get = _to_string
  30. var bytes: PackedByteArray: get = to_bytes
  31. var chars: PackedByteArray: get = to_chars
  32.  
  33. func _init(p_vector: PackedInt64Array = [0], p_is_negative: bool = false) -> void:
  34.     self.value = BigNumber.atomize_vector(p_vector)
  35.     self.is_negative = p_is_negative
  36.  
  37.     while self.value.size() > 1 and self.value[-1] == 0:
  38.         self.value.resize(self.value.size() - 1)
  39.    
  40.     if self.value.size() == 0:
  41.         self.value = [ 0 ]
  42.  
  43. static func from_bytes(p_bytes: PackedByteArray) -> BigNumber:
  44.     var result = BigNumber.new()
  45.     result.value = []
  46.    
  47.     var temp := 0
  48.     var base := 1
  49.    
  50.     for byte in p_bytes:
  51.         if base > floor(ATOMIC_MAX) / 256:
  52.             result.value.append(temp)
  53.             temp = byte
  54.             base = 1
  55.         else:
  56.             temp += byte * base
  57.             base *= 256
  58.    
  59.     if temp > 0 or result.value.size() == 0:
  60.         result.value.append(temp)
  61.    
  62.     return result
  63.  
  64. func to_bytes() -> PackedByteArray:
  65.     var result := PackedByteArray()
  66.  
  67.     for _value: int in self.value:
  68.         var temp := _value
  69.         while temp > 0:
  70.             result.append(temp % 256)
  71.             @warning_ignore("integer_division")
  72.             temp = temp / 256
  73.         while len(result) % 4 != 0:
  74.             result.append(0)
  75.    
  76.     return result
  77.  
  78. static func from_chars(p_bytes: PackedByteArray) -> BigNumber:
  79.     var result := BigNumber.new()
  80.     result.value = []
  81.    
  82.     var temp := 0
  83.     var base := 1
  84.    
  85.     for byte in p_bytes:
  86.         if base > floor(ATOMIC_MAX) / 127:
  87.             result.value.append(temp)
  88.             temp = byte
  89.             base = 1
  90.         else:
  91.             temp += byte * base
  92.             base *= 127
  93.    
  94.     if temp > 0 or result.value.size() == 0:
  95.         result.value.append(temp)
  96.    
  97.     return result
  98.  
  99. func to_chars() -> PackedByteArray:
  100.     var result := PackedByteArray()
  101.  
  102.     for _value in self.value:
  103.         var temp := _value
  104.         while temp > 0:
  105.             result.append(temp % 127)
  106.             @warning_ignore("integer_division")
  107.             temp = temp / 127
  108.         while len(result) % 4 != 0:
  109.             result.append(0)
  110.    
  111.     return result
  112.  
  113. static func from_int(p_number: int) -> BigNumber:
  114.     if p_number == 0:
  115.         var empty: PackedInt64Array = [ 0 ]
  116.         return BigNumber.new(empty)
  117.    
  118.     var number := absi(p_number)
  119.     var result: PackedInt64Array = []
  120.  
  121.     while number > 0:
  122.         result.append(number % ATOMIC_MAX)
  123.         number /= ATOMIC_MAX
  124.  
  125.     return BigNumber.new(result, p_number < 0)
  126.  
  127. static func from_uint(p_number: int) -> BigNumber:
  128.     if p_number == 0:
  129.         var empty: PackedInt64Array = [ 0 ]
  130.         return BigNumber.new(empty)
  131.    
  132.     var number := p_number
  133.     var result: PackedInt64Array = []
  134.  
  135.     while number > 0:
  136.         result.append(number % ATOMIC_MAX)
  137.         number /= ATOMIC_MAX
  138.  
  139.     return BigNumber.new(result)
  140.  
  141. static func from_string_base(p_number: String, p_base: int) -> BigNumber:
  142.     var number_str := p_number
  143.     var _is_negative := false
  144.  
  145.     if number_str[0] == "-":
  146.         _is_negative = true
  147.         number_str = number_str.substr(1)
  148.  
  149.     var bn := BigNumber.new()
  150.     for i in number_str:
  151.         var digit_value := BASE_DIGITS.find(i)
  152.         if digit_value == -1 or digit_value >= p_base:
  153.             return BigNumber.new()
  154.         bn = bn.multiply_uint(p_base)
  155.         bn = bn.add_uint(digit_value)
  156.  
  157.     bn.is_negative = _is_negative
  158.  
  159.     return bn
  160.  
  161. static func from_string(p_number: String) -> BigNumber:
  162.     return BigNumber.from_string_base(p_number, 10)
  163.  
  164. static func from_hex(p_number: String) -> BigNumber:
  165.     var number := p_number
  166.     if number.substr(0, 2) == "0x":
  167.         number = number.substr(2)
  168.    
  169.     return BigNumber.from_string_base(number, 16)
  170.  
  171. static func from_random(p_bits: int) -> BigNumber:
  172.     var bytes_num := ceili(p_bits / ATOMIC_BITS_F)
  173.    
  174.     var scalars: PackedInt64Array = []
  175.    
  176.     for i in range(bytes_num):
  177.         scalars.append(randi_range(0, ATOMIC_MAX))
  178.    
  179.     return BigNumber.new(scalars)
  180.  
  181. static func from_random_range(p_min: BigNumber, p_max: BigNumber) -> BigNumber:
  182.     var _range := p_max.subtract(p_min)
  183.     var scalars: PackedInt64Array = []
  184.    
  185.     for i in range(_range.value.size()):
  186.         scalars.append(randi_range(0, ATOMIC_MAX))
  187.    
  188.     var result := BigNumber.new(scalars)
  189.     result = result.add(p_min)
  190.  
  191.     if result.is_greater_than(p_max):
  192.         result = p_max.duplicate()
  193.    
  194.     return result
  195.  
  196. static func atomize(p_scalar: int) -> int:
  197.     return p_scalar % ATOMIC_MAX
  198.  
  199. static func atomize_vector(p_vector: PackedInt64Array) -> PackedInt64Array:
  200.     var size := p_vector.size()
  201.     var result: PackedInt64Array = []
  202.     result.resize(size)
  203.     for i: int in range(size):
  204.         result[i] = p_vector[i] % ATOMIC_MAX
  205.     return result
  206.  
  207. func duplicate() -> BigNumber:
  208.     return BigNumber.new(self.value.duplicate(), self.is_negative)
  209.  
  210. func abs() -> BigNumber:
  211.     var result: BigNumber = self.duplicate()
  212.     result.is_negative = false
  213.     return result
  214.  
  215. func add(p_other: BigNumber) -> BigNumber:
  216.     if self.is_negative and p_other.is_negative:
  217.         var a := self.duplicate()
  218.         var b := p_other.duplicate()
  219.  
  220.         a.is_negative = false
  221.         b.is_negative = false
  222.  
  223.         var added := a.add(b)
  224.         added.is_negative = true
  225.         return added
  226.     elif self.is_negative or p_other.is_negative:
  227.         var a := self.duplicate()
  228.         var b := p_other.duplicate()
  229.  
  230.         var a_is_negative := a.is_negative
  231.         var b_is_negative := b.is_negative
  232.  
  233.         a.is_negative = false
  234.         b.is_negative = false
  235.  
  236.         if a.is_greater_than(b):
  237.             var subtracted := a.subtract(b)
  238.             subtracted.is_negative = a_is_negative
  239.             return subtracted
  240.         elif b.is_greater_than(a):
  241.             var subtracted := b.subtract(a)
  242.             subtracted.is_negative = b_is_negative
  243.             return subtracted
  244.         else:
  245.             return BigNumber.from_uint(0)
  246.    
  247.     var result: PackedInt64Array = []
  248.     var carry := 0
  249.     var max_length := maxi(self.value.size(), p_other.value.size())
  250.     result.resize(max_length)
  251.    
  252.     for i: int in range(max_length):
  253.         var sum := carry
  254.         if i < self.value.size():
  255.             sum += self.value[i]
  256.         if i < p_other.value.size():
  257.             sum += p_other.value[i]
  258.        
  259.         result[i] = sum % ATOMIC_MAX
  260.         @warning_ignore("integer_division")
  261.         carry = sum / ATOMIC_MAX
  262.  
  263.     if carry > 0:
  264.         result.append(carry)
  265.  
  266.     return BigNumber.new(result)
  267.  
  268. func subtract(p_other: BigNumber) -> BigNumber:
  269.     var result: PackedInt64Array = []
  270.     var _is_negative: bool = false
  271.     var other: BigNumber
  272.  
  273.     if self.is_negative and p_other.is_negative:
  274.         var a := BigNumber.new(self.value.duplicate())
  275.         var b := BigNumber.new(p_other.value.duplicate())
  276.  
  277.         a.is_negative = false
  278.         b.is_negative = false
  279.  
  280.         var subtracted: BigNumber
  281.  
  282.         if a.is_greater_than(b):
  283.             subtracted = a.subtract(b)
  284.             subtracted.is_negative = true
  285.             return subtracted
  286.         else:
  287.             subtracted = b.subtract(a)
  288.             subtracted.is_negative = false
  289.             return subtracted
  290.     elif self.is_negative:
  291.         var a := BigNumber.new(self.value.duplicate())
  292.         var b := BigNumber.new(p_other.value.duplicate())
  293.  
  294.         a.is_negative = false
  295.         b.is_negative = false
  296.  
  297.         var added := a.add(b)
  298.         added.is_negative = true
  299.         return added
  300.     elif p_other.is_negative:
  301.         var a := BigNumber.new(self.value.duplicate())
  302.         var b := BigNumber.new(p_other.value.duplicate())
  303.  
  304.         a.is_negative = false
  305.         b.is_negative = false
  306.  
  307.         var added := a.add(b)
  308.         added.is_negative = false
  309.         return added
  310.    
  311.     if self.is_less_than(p_other):
  312.         result = p_other.value.duplicate()
  313.         other = self
  314.         _is_negative = true
  315.     else:
  316.         result = self.value.duplicate()
  317.         other = p_other
  318.  
  319.     var borrow := 0
  320.  
  321.     for i: int in range(result.size()):
  322.         var subtrahend := 0
  323.         if i < other.value.size():
  324.             subtrahend = other.value[i];
  325.         if result[i] < subtrahend + borrow:
  326.             result[i] = result[i] + ATOMIC_MAX - subtrahend - borrow
  327.             borrow = 1
  328.         else:
  329.             result[i] = result[i] - subtrahend - borrow
  330.             borrow = 0
  331.  
  332.     while result.size() > 1 and result[-1] == 0:
  333.         result.resize(result.size() - 1)
  334.  
  335.     return BigNumber.new(result, _is_negative)
  336.  
  337. func multiply(p_other: BigNumber) -> BigNumber:
  338.     var _is_negative := self.is_negative != p_other.is_negative
  339.  
  340.     var other := p_other.duplicate()
  341.     other.is_negative = false
  342.  
  343.     var smaller: PackedInt64Array
  344.     var larger: PackedInt64Array
  345.  
  346.     if self.value.size() < other.value.size():
  347.         smaller = self.value.duplicate()
  348.         larger = other.value
  349.     else:
  350.         smaller = other.value
  351.         larger = self.value.duplicate()
  352.  
  353.     var _value := larger.duplicate()
  354.  
  355.     var result: BigNumber = BigNumber.from_uint(0)
  356.     var carry := 0
  357.  
  358.     for i: int in range(smaller.size()):
  359.         var temp: PackedInt64Array = []
  360.         temp.resize(_value.size())
  361.         for j: int in range(_value.size()):
  362.             var product = smaller[i] * _value[j] + carry
  363.             temp.append(product % ATOMIC_MAX)
  364.             @warning_ignore("integer_division")
  365.             carry = product / ATOMIC_MAX
  366.         while carry > 0:
  367.             temp.append(carry % ATOMIC_MAX)
  368.             carry /= ATOMIC_MAX
  369.         result = result.add(BigNumber.new(temp))
  370.    
  371.     result.is_negative = _is_negative
  372.    
  373.     return result
  374.  
  375. func divide(p_divisor: BigNumber) -> BigNumber:
  376.     var divisor := p_divisor.duplicate()
  377.     var _is_negative := self.is_negative != divisor.is_negative
  378.  
  379.     divisor.is_negative = false
  380.    
  381.     assert(not divisor.is_zero(), "Error: Division by zero")
  382.  
  383.     if self.is_less_than(divisor):
  384.         return BigNumber.from_uint(0)
  385.  
  386.     if self.is_equal_to(divisor):
  387.         return BigNumber.from_uint(1)
  388.  
  389.     var dividend := self.duplicate()
  390.     dividend.is_negative = false
  391.     var quotient := BigNumber.from_uint(0)
  392.  
  393.     while not dividend.is_less_than(divisor):
  394.         var temp := divisor
  395.         var multiple := BigNumber.ONE.duplicate()
  396.         while dividend.is_greater_than(temp.shift_left_uint(1)):
  397.             temp = temp.shift_left_uint(1)
  398.             multiple = multiple.shift_left_uint(1)
  399.         dividend = dividend.subtract(temp)
  400.         quotient = quotient.add(multiple)
  401.  
  402.     if not quotient.is_zero():
  403.         quotient.is_negative = _is_negative
  404.  
  405.     return quotient
  406.  
  407. func mutable_increment():
  408.     var _is_positive = self.is_zero() or not self.is_negative
  409.    
  410.     self.value[0] += 1
  411.     var carry = 0
  412.     for i in range(self.value.size()):
  413.         self.value[i] += carry
  414.         if self.value[i] > ATOMIC_MAX:
  415.             self.value[i] -= ATOMIC_MAX
  416.             carry = 1
  417.         else:
  418.             carry = 0
  419.     if carry > 0:
  420.         self.value.append(carry)
  421.    
  422.     self.is_negative = not _is_positive
  423.  
  424. func mutable_decrement():
  425.     var _is_negative := self.is_zero() or self.is_negative
  426.  
  427.     self.value[0] -= 1
  428.     var borrow := 0
  429.     for i in range(self.value.size()):
  430.         self.value[i] -= borrow
  431.         if self.value[i] < 0:
  432.             self.value[i] += ATOMIC_MAX
  433.             borrow = 1
  434.         else:
  435.             borrow = 0
  436.     while self.value.size() > 1 and self.value[-1] == 0:
  437.         self.value.resize(self.value.size() - 1)
  438.    
  439.     self.is_negative = _is_negative
  440.  
  441. func increment() -> BigNumber:
  442.     var result: BigNumber = self.duplicate()
  443.     result.mutable_increment()
  444.     return result
  445.  
  446. func decrement() -> BigNumber:
  447.     var result: BigNumber = self.duplicate()
  448.     result.mutable_decrement()
  449.     return result
  450.  
  451. func power(p_exponent: BigNumber) -> BigNumber:
  452.     if p_exponent.is_zero():
  453.         return BigNumber.from_uint(1)
  454.     if p_exponent.is_negative:
  455.         print_debug(" Negative power is given. BigNumber doesn't have floating point numbers support. Returning 0...")
  456.         return BigNumber.from_uint(0)
  457.    
  458.     var result: BigNumber = self.duplicate()
  459.     var exponent = p_exponent.subtract(BigNumber.ONE)
  460.  
  461.     while exponent.is_greater_than(BigNumber.ZERO):
  462.         result = result.multiply(self)
  463.         exponent = exponent.decrement()
  464.  
  465.     return result
  466.  
  467. func power_uint(p_exponent: int) -> BigNumber:
  468.     return self.power(BigNumber.from_uint(p_exponent))
  469.  
  470. func sqrt() -> BigNumber:
  471.     if self.is_zero():
  472.         return BigNumber.from_uint(0)
  473.    
  474.     var x := self.duplicate()
  475.     var y := x.add(BigNumber.from_uint(1)).shift_right_uint(1)
  476.  
  477.     while y.is_less_than(x):
  478.         x = y
  479.         y = x.add(self.divide(x)).shift_right_uint(1)
  480.  
  481.     return x
  482.  
  483. func mutable_modulo(p_modulus: BigNumber):
  484.     var remainder: BigNumber = BigNumber.from_uint(0)
  485.    
  486.     for i in range((self.value.size() * ATOMIC_BITS) - 1, -1, -1):
  487.         remainder = remainder.shift_left_uint(1)
  488.         @warning_ignore("integer_division")
  489.         remainder.value[0] |= (self.value[int(i / ATOMIC_BITS)] >> (i % ATOMIC_BITS)) & 1
  490.         if remainder.compare(p_modulus) >= 0:
  491.             remainder.mutable_subtract(p_modulus)
  492.  
  493.     self.is_negative = p_modulus.is_negative
  494.     self.value = remainder.value
  495.  
  496. func modulo(p_modulus: BigNumber) -> BigNumber:
  497.     var other := p_modulus.duplicate()
  498.     other.is_negative = false
  499.     var _is_negative := other.is_negative
  500.     var result: BigNumber = self.duplicate()
  501.     result.is_negative = false
  502.     result.mutable_modulo(other)
  503.     result.is_negative = _is_negative
  504.     return result
  505.  
  506. func bit_and(p_other: BigNumber) -> BigNumber:
  507.     var other = p_other.duplicate()
  508.     var result: PackedInt64Array = []
  509.  
  510.     var max_length := maxi(self.value.size(), other.value.size())
  511.     for i: int in range(max_length):
  512.         var anded := 0
  513.         if i < self.value.size():
  514.             anded = self.value[i]
  515.         if i < other.value.size():
  516.             anded &= other.value[i]
  517.         result.append(anded)
  518.  
  519.     return BigNumber.new(result)
  520.  
  521. func bit_or(p_other: BigNumber) -> BigNumber:
  522.     var other := p_other.duplicate()
  523.     var result: PackedInt64Array = []
  524.  
  525.     var max_length := maxi(self.value.size(), other.value.size())
  526.     for i: int in range(max_length):
  527.         var ored := 0
  528.         if i < self.value.size():
  529.             ored = self.value[i]
  530.         if i < other.value.size():
  531.             ored |= other.value[i]
  532.         result.append(ored)
  533.  
  534.     return BigNumber.new(result)
  535.  
  536. func bit_xor(p_other: BigNumber) -> BigNumber:
  537.     var other := p_other.duplicate()
  538.     var result: PackedInt64Array = []
  539.  
  540.     var max_length := maxi(self.value.size(), other.value.size())
  541.     for i: int in range(max_length):
  542.         var xored := 0
  543.         if i < self.value.size():
  544.             xored = self.value[i]
  545.         if i < other.value.size():
  546.             xored ^= other.value[i]
  547.         result.append(xored)
  548.  
  549.     return BigNumber.new(result)
  550.  
  551. func and_uint(p_number: int) -> BigNumber:
  552.     return self.bit_and(BigNumber.from_uint(p_number))
  553.  
  554. func or_uint(p_number: int) -> BigNumber:
  555.     return self.bit_or(BigNumber.from_uint(p_number))
  556.  
  557. func shift_left_uint(p_shift: int) -> BigNumber:
  558.     var result: PackedInt64Array = self.value.duplicate()
  559.     var carry := 0
  560.     var temp := 0
  561.  
  562.     for i: int in range(result.size()):
  563.         temp = result[i]
  564.         result[i] = (result[i] << p_shift) | carry
  565.         carry = (temp >> (ATOMIC_BITS - p_shift)) & ATOMIC_MAX_MINUS_ONE
  566.    
  567.     if carry > 0:
  568.         result.append(carry)
  569.    
  570.     return BigNumber.new(result)
  571.  
  572. func shift_left(p_shift: BigNumber) -> BigNumber:
  573.     var result: PackedInt64Array = self.value.duplicate()
  574.     var carry := 0
  575.     var temp := 0
  576.    
  577.     for i: int in range(result.size()):
  578.         temp = result[i]
  579.         result[i] = (result[i] << p_shift.to_uint()) | carry
  580.         carry = (temp >> (ATOMIC_BITS - p_shift.to_uint())) & ATOMIC_MAX_MINUS_ONE
  581.  
  582.     if carry > 0:
  583.         result.append(carry)
  584.  
  585.     return BigNumber.new(result)
  586.  
  587. func shift_right_uint(p_shift: int) -> BigNumber:
  588.     var result: PackedInt64Array = self.value.duplicate()
  589.     var carry = 0
  590.     var temp = 0
  591.  
  592.     for i: int in range(result.size() - 1, -1, -1):
  593.         temp = result[i]
  594.         result[i] = (result[i] >> p_shift) | carry
  595.         carry = (temp << (ATOMIC_BITS - p_shift)) & ATOMIC_MAX_MINUS_ONE
  596.  
  597.     while result.size() > 1 and result[-1] == 0:
  598.         result.resize(result.size() - 1)
  599.  
  600.     return BigNumber.new(result)
  601.  
  602. func shift_right(p_shift: BigNumber) -> BigNumber:
  603.     var result: PackedInt64Array = self.value.duplicate()
  604.     var carry := 0
  605.     var temp := 0
  606.  
  607.     for i: int in range(result.size() - 1, -1, -1):
  608.         temp = result[i]
  609.         result[i] = (result[i] >> p_shift.to_uint()) | carry
  610.         carry = (temp << (ATOMIC_BITS - p_shift.to_uint())) & ATOMIC_MAX_MINUS_ONE
  611.  
  612.     while result.size() > 1 and result[-1] == 0:
  613.         result.resize(result.size() - 1)
  614.  
  615.     return BigNumber.new(result)
  616.  
  617. func mutable_subtract(p_other: BigNumber) -> void:
  618.     var borrow := 0
  619.     for i in range(p_other.value.size()):
  620.         var diff: int = self.value[i] - p_other.value[i] - borrow
  621.         if diff < 0:
  622.             diff += ATOMIC_MAX
  623.             borrow = 1
  624.         else:
  625.             borrow = 0
  626.         self.value[i] = diff
  627.     for i in range(p_other.value.size(), self.value.size()):
  628.         if borrow == 0:
  629.             break
  630.         var diff := self.value[i] - borrow
  631.         if diff < 0:
  632.             diff += ATOMIC_MAX
  633.             borrow = 1
  634.         else:
  635.             borrow = 0
  636.         self.value[i] = diff
  637.     while self.value.size() > 1 and self.value[-1] == 0:
  638.         self.value.remove_at(self.value.size() - 1)
  639.  
  640. func is_zero() -> bool:
  641.     return self.value.size() == 1 and self.value[0] == 0
  642.  
  643. func is_even() -> bool:
  644.     return (self.value[0] & 1) == 0
  645.  
  646. func is_odd() -> bool:
  647.     return (self.value[0] & 1) == 1
  648.  
  649. func power_modulo(p_exponent: BigNumber, p_modulus: BigNumber) -> BigNumber:
  650.     var result := BigNumber.from_uint(1)
  651.     var base := self.modulo(p_modulus)
  652.  
  653.     while not p_exponent.is_zero():
  654.         if p_exponent.is_odd():
  655.             result = result.multiply(base).modulo(p_modulus)
  656.         base = base.multiply(base).modulo(p_modulus)
  657.         p_exponent = p_exponent.shift_right_uint(1)
  658.  
  659.     return result
  660.  
  661. func prime_inverse_modulo(p_modulus: BigNumber) -> BigNumber:
  662.     var g := self.gcd(p_modulus)
  663.    
  664.     assert(g.is_equal_to(BigNumber.ONE), "Error: " + self._to_string() + " is not invertible")
  665.    
  666.     var mmt := p_modulus.subtract(BigNumber.from_uint(2))
  667.     var inverted := self.power_modulo(mmt, p_modulus)
  668.  
  669.     return inverted
  670.  
  671. func inverse_modulo(p_modulus: BigNumber) -> BigNumber:
  672.     var t := BigNumber.from_uint(0)
  673.     var newt := BigNumber.from_uint(1)
  674.  
  675.     var r := p_modulus.duplicate()
  676.     var newr := self.duplicate()
  677.  
  678.     while not newr.is_zero():
  679.         var quotient := r.divide(newr)
  680.        
  681.         var temp := newt.duplicate()
  682.         newt = t.subtract(quotient.multiply(newt))
  683.         t = temp
  684.        
  685.         temp = newr.duplicate()
  686.         newr = r.subtract(quotient.multiply(newr))
  687.         r = temp
  688.    
  689.     assert(r.is_equal_to(BigNumber.ONE), "Error: " + self._to_string() + " is not invertible")
  690.    
  691.     if t.is_negative:
  692.         t = t.add(p_modulus)
  693.    
  694.     return t
  695.  
  696. func compare(p_other: BigNumber) -> int:
  697.     if self.is_negative and not p_other.is_negative:
  698.         return -1
  699.     elif not self.is_negative and p_other.is_negative:
  700.         return 1
  701.     elif self.is_negative and p_other.is_negative:
  702.         var a := self.duplicate()
  703.         var b := p_other.duplicate()
  704.         a.is_negative = false
  705.         b.is_negative = false
  706.         return a.compare(b) * -1
  707.  
  708.     if self.value.size() > p_other.value.size():
  709.         return 1
  710.     elif self.value.size() < p_other.value.size():
  711.         return -1
  712.     else:
  713.         for i: int in range(self.value.size() - 1, -1, -1):
  714.             if self.value[i] > p_other.value[i]:
  715.                 return 1
  716.             elif self.value[i] < p_other.value[i]:
  717.                 return -1
  718.         return 0
  719.  
  720. func is_greater_than(p_other: BigNumber) -> bool:
  721.     return self.compare(p_other) == 1
  722.  
  723. func is_less_than(p_other: BigNumber) -> bool:
  724.     return self.compare(p_other) == -1
  725.  
  726. func is_equal_to(p_other: BigNumber) -> bool:
  727.     return self.compare(p_other) == 0
  728.  
  729. func is_greater_than_or_equal_to(p_other: BigNumber) -> bool:
  730.     return self.compare(p_other) >= 0
  731.  
  732. func is_less_than_or_equal_to(p_other: BigNumber) -> bool:
  733.     return self.compare(p_other) <= 0
  734.  
  735. func gcd(p_other: BigNumber) -> BigNumber:
  736.     var a: BigNumber = self
  737.     var b: BigNumber = p_other
  738.    
  739.     while not a.is_zero():
  740.         var t := a
  741.         a = b.modulo(a)
  742.         b = t
  743.    
  744.     return b
  745.  
  746. func add_int(p_number: int) -> BigNumber:
  747.     var number := absi(p_number)
  748.     var bn := BigNumber.from_uint(number)
  749.     bn.is_negative = p_number < 0
  750.     return self.add(bn)
  751.  
  752. func add_uint(p_number: int) -> BigNumber:
  753.     return self.add(BigNumber.from_uint(p_number))
  754.  
  755. func subtract_int(p_number: int) -> BigNumber:
  756.     var number := absi(p_number)
  757.     var bn := BigNumber.from_uint(number)
  758.     bn.is_negative = p_number < 0
  759.     return self.subtract(bn)
  760.  
  761. func subtract_uint(p_number: int) -> BigNumber:
  762.     return self.subtract(BigNumber.from_uint(p_number))
  763.  
  764. func multiply_int(p_number: int) -> BigNumber:
  765.     var number := absi(p_number)
  766.     var bn := BigNumber.from_uint(number)
  767.     bn.is_negative = p_number < 0
  768.     return self.multiply(bn)
  769.  
  770. func multiply_uint(p_number: int) -> BigNumber:
  771.     return self.multiply(BigNumber.from_uint(p_number))
  772.  
  773. func divide_int(p_number: int) -> BigNumber:
  774.     var number := absi(p_number)
  775.     var bn := BigNumber.from_uint(number)
  776.     bn.is_negative = p_number < 0
  777.     return self.divide(bn)
  778.  
  779. func divide_uint(p_number: int) -> BigNumber:
  780.     return self.divide(BigNumber.from_uint(p_number))
  781.  
  782. func to_uint() -> int:
  783.     var result := 0
  784.     for i in range(self.value.size() - 1, -1, -1):
  785.         result = result * ATOMIC_MAX + self.value[i]
  786.  
  787.     if self.is_negative:
  788.         result *= 2
  789.         result += 1
  790.  
  791.     return result
  792.  
  793. func to_int() -> int:
  794.     var result := 0
  795.     for i in range(self.value.size() - 1, -1, -1):
  796.         result = result * ATOMIC_MAX + self.value[i]
  797.    
  798.     if self.is_negative:
  799.         result *= -1
  800.    
  801.     return result
  802.  
  803. func to_string_base(p_base: int) -> String:
  804.     if p_base < 2 or p_base > BASE_DIGITS.length():
  805.         print_debug("Invalid base: " + str(p_base))
  806.         return ""
  807.  
  808.     var result: PackedStringArray = []
  809.     var number: PackedInt64Array = self.value.duplicate()
  810.  
  811.     while number.size() > 0:
  812.         var remainder := 0
  813.         for i in range(number.size() - 1, -1, -1):
  814.             var temp = remainder * ATOMIC_MAX + number[i]
  815.             @warning_ignore("integer_division")
  816.             number[i] = temp / p_base
  817.             remainder = temp % p_base
  818.  
  819.         while number.size() > 0 and number[number.size() - 1] == 0:
  820.             number.remove_at(number.size() - 1)
  821.  
  822.         result.append(BASE_DIGITS[remainder])
  823.  
  824.     if result.size() == 0:
  825.         return "0"
  826.    
  827.     var str_result: String = ""
  828.     for i in range(result.size() - 1, -1, -1):
  829.         str_result += str(result[i])
  830.  
  831.     if self.is_negative:
  832.         str_result = "-" + str_result
  833.  
  834.     return str_result
  835.  
  836. func to_hex(p_prefix: String = "0x") -> String:
  837.     return p_prefix + self.to_string_base(16)
  838.  
  839. func _to_string() -> String:
  840.     return self.to_string_base(10)
  841.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement