Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Math.bigint in SC #1550

Merged
merged 2 commits into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions lib/archethic/contracts/interpreter/library/common/math.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ defmodule Archethic.Contracts.Interpreter.Library.Common.Math do

alias Archethic.Tag
alias Archethic.Contracts.Interpreter.ASTHelper, as: AST
alias Archethic.Contracts.Interpreter.Library

use Tag
import Bitwise
Expand Down Expand Up @@ -127,6 +128,50 @@ defmodule Archethic.Contracts.Interpreter.Library.Common.Math do
to_number(res, is_integer(num1) and is_integer(num2))
end

@doc """

## Example

iex> Math.bigint(49.85024327, 18)
49_850_243_270_000_000_000

iex> Math.bigint(1.994e-4, 18)
199_400_000_000_000

iex> Math.bigint(0.19941234, 18)
199_412_340_000_000_000

iex> Math.bigint(0.10000006, 18)
100_000_060_000_000_000

iex> Math.bigint(0.002, 18)
2_000_000_000_000_000

iex> Math.bigint(1.2390131, 18)
1_239_013_100_000_000_000

iex> Math.bigint(10, 18)
10_000_000_000_000_000_000

iex> Math.bigint(1, 8)
100_000_000

"""
@spec bigint(num :: number(), decimals :: number()) :: number()
def bigint(num, decimals) do
num
|> to_string()
|> Decimal.new()
|> Decimal.mult(Decimal.new(10 ** decimals))
|> then(fn dec ->
if Decimal.integer?(dec) do
Decimal.to_integer(dec)
else
raise Library.Error, message: "Number exceeds decimals"
end
end)
end

@spec check_types(atom(), list()) :: boolean()
def check_types(:trunc, [first]) do
AST.is_number?(first) || AST.is_variable_or_function_call?(first)
Expand All @@ -146,6 +191,11 @@ defmodule Archethic.Contracts.Interpreter.Library.Common.Math do
(AST.is_number?(second) || AST.is_variable_or_function_call?(second))
end

def check_types(:bigint, [first, second]) do
(AST.is_number?(first) || AST.is_variable_or_function_call?(first)) &&
(AST.is_number?(second) || AST.is_variable_or_function_call?(second))
end

def check_types(_, _), do: false

defp to_decimal(num) when is_integer(num), do: Decimal.new(num)
Expand Down
11 changes: 11 additions & 0 deletions test/archethic/contracts/interpreter/library/common/math_test.exs
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
defmodule Archethic.Contracts.Interpreter.Library.Common.MathTest do
use ArchethicCase

alias Archethic.Contracts.Interpreter.Library
alias Archethic.Contracts.Interpreter.Library.Common.Math

doctest Math

test "exceed decimals raise" do
assert_raise Library.Error, "Number exceeds decimals", fn ->
Math.bigint(0.1234, 2)
end

assert_raise Library.Error, "Number exceeds decimals", fn ->
Math.bigint(0.12345874564, 8)
end
end
end
Loading