import gleam/order /// A big integer. pub type BigInt /// Create a big integer representing zero. @external(erlang, "bigi_ffi", "zero") @external(javascript, "./bigi_ffi.mjs", "zero") pub fn zero() -> BigInt /// Create a big integer from a regular integer. @external(erlang, "bigi_ffi", "from") @external(javascript, "./bigi_ffi.mjs", "from") pub fn from_int(int: Int) -> BigInt /// Convert the big integer to a regular integer. /// /// In Erlang, this cannot fail, as all Erlang integers are big integers. In the /// JavaScript target, this will fail if the integer is bigger than the /// [maximum safe integer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER) /// or smaller than the /// [minimum safe integer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MIN_SAFE_INTEGER). @external(erlang, "bigi_ffi", "to") @external(javascript, "./bigi_ffi.mjs", "to") pub fn to_int(bigint: BigInt) -> Result(Int, Nil) /// Convert the big integer into a simple string - a sequence of digits. @external(erlang, "erlang", "integer_to_binary") @external(javascript, "./bigi_ffi.mjs", "to_string") pub fn to_string(bigint: BigInt) -> String /// Compare two big integers, returning an order that denotes if `b` is lower, /// bigger than, or equal to `a`. @external(erlang, "bigi_ffi", "compare") @external(javascript, "./bigi_ffi.mjs", "compare") pub fn compare(a: BigInt, with b: BigInt) -> order.Order /// Get the absolute value of a big integer. @external(erlang, "erlang", "abs") @external(javascript, "./bigi_ffi.mjs", "absolute") pub fn absolute(bigint: BigInt) -> BigInt /// Add two big integers together. @external(erlang, "bigi_ffi", "add") @external(javascript, "./bigi_ffi.mjs", "add") pub fn add(a: BigInt, b: BigInt) -> BigInt /// Subtract the subtrahend from the minuend. @external(erlang, "bigi_ffi", "subtract") @external(javascript, "./bigi_ffi.mjs", "subtract") pub fn subtract(minuend a: BigInt, subtrahend b: BigInt) -> BigInt /// Multiply two big integers together. @external(erlang, "bigi_ffi", "multiply") @external(javascript, "./bigi_ffi.mjs", "multiply") pub fn multiply(a: BigInt, b: BigInt) -> BigInt /// Divide the dividend with the divisor using integer division. /// /// Follows the standard Gleam divide-by-zero rule of 0 when the divisor is 0. @external(erlang, "bigi_ffi", "divide") @external(javascript, "./bigi_ffi.mjs", "divide") pub fn divide(dividend a: BigInt, divisor b: BigInt) -> BigInt /// Divide the dividend with the divisor using integer division. /// /// Returns an error if the divisor is 0. @external(erlang, "bigi_ffi", "divide_no_zero") @external(javascript, "./bigi_ffi.mjs", "divide_no_zero") pub fn divide_no_zero( dividend a: BigInt, divisor b: BigInt, ) -> Result(BigInt, Nil) /// Divide the dividend with the divisor using integer division and return the /// remainder. /// /// Follows the standard Gleam divide-by-zero rule of 0 when the divisor is 0. @external(erlang, "bigi_ffi", "remainder") @external(javascript, "./bigi_ffi.mjs", "remainder") pub fn remainder(dividend a: BigInt, divisor b: BigInt) -> BigInt /// Divide the dividend with the divisor using integer division and return the /// remainder. /// /// Returns an error if the divisor is 0. @external(erlang, "bigi_ffi", "remainder_no_zero") @external(javascript, "./bigi_ffi.mjs", "remainder_no_zero") pub fn remainder_no_zero( dividend a: BigInt, divisor b: BigInt, ) -> Result(BigInt, Nil) /// Calculate a mathematical modulo operation. /// /// Follows the standard Gleam divide-by-zero rule of 0 when the divisor is 0. @external(erlang, "bigi_ffi", "modulo") @external(javascript, "./bigi_ffi.mjs", "modulo") pub fn modulo(dividend a: BigInt, divisor b: BigInt) -> BigInt /// Calculate a mathematical modulo operation. /// /// Returns an error if the divisor is 0. @external(erlang, "bigi_ffi", "modulo_no_zero") @external(javascript, "./bigi_ffi.mjs", "modulo_no_zero") pub fn modulo_no_zero( dividend a: BigInt, divisor b: BigInt, ) -> Result(BigInt, Nil) /// Raise the base to the exponent. /// /// If the exponent is negative, an error is returned. @external(erlang, "bigi_ffi", "power") @external(javascript, "./bigi_ffi.mjs", "power") pub fn power(base a: BigInt, exponent b: BigInt) -> Result(BigInt, Nil) /// Get the digits in a given bigint as a list of integers. /// /// The list is ordered starting from the most significant digit. pub fn digits(bigint: BigInt) { let divisor = from_int(10) get_digit(bigint, [], divisor) } fn get_digit(bigint: BigInt, digits: List(Int), divisor: BigInt) { case compare(bigint, divisor) { order.Gt -> { let assert Ok(digit) = to_int(bigint) [digit, ..digits] } _ -> { let assert Ok(digit) = remainder(bigint, divisor) |> to_int() let digits = [digit, ..digits] get_digit(divide(bigint, divisor), digits, divisor) } } }