Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:20
decimal
decimal-2.0.0-git.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File decimal-2.0.0-git.patch of Package decimal
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b39f085..3a9be0c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,36 +7,50 @@ on: - master jobs: - mix_test: - name: mix test (Erlang/OTP ${{matrix.otp}} | Elixir ${{matrix.elixir}}) - runs-on: ubuntu-latest + test: + runs-on: ubuntu-18.04 + env: + MIX_ENV: test strategy: fail-fast: false matrix: include: - - elixir: 1.2.6 - otp: 18.3.4.11 - - elixir: 1.10.4 - otp: 23.0.3 + - pair: + elixir: 1.2.6 + otp: 18.3.4.11 + - pair: + elixir: 1.11.4 + otp: 23.3.x + - pair: + elixir: 1.12.x + otp: 23.3.x + - pair: + elixir: 1.13.x + otp: 24.3.x + - pair: + elixir: 1.14.x + otp: 25.x + lint: lint steps: - - uses: actions/checkout@v2.3.1 - - uses: actions/setup-elixir@v1.3.0 + - uses: actions/checkout@v3 + + - uses: erlef/setup-beam@v1 with: - otp-version: ${{matrix.otp}} - elixir-version: ${{matrix.elixir}} + otp-version: ${{matrix.pair.otp}} + elixir-version: ${{matrix.pair.elixir}} + - name: Install Dependencies - run: | - mix local.hex --force - mix deps.get --only test - - run: mix test + run: mix deps.get --only test - check_formatted: - name: Check formatted - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2.3.1 - - uses: actions/setup-elixir@v1.3.0 - with: - otp-version: 23.0.3 - elixir-version: 1.10.4 - run: mix format --check-formatted + if: ${{ matrix.lint }} + + - run: mix deps.get && mix deps.unlock --check-unused + if: ${{ matrix.lint }} + + - run: mix deps.compile + + - run: mix compile --warnings-as-errors + if: ${{ matrix.lint }} + + - run: mix test diff --git a/README.md b/README.md index 6584a9f..12c9db6 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,26 @@ Arbitrary precision decimal arithmetic. +## Concept + +Decimal represents values internally using three integers: a sign, a coefficient, and an exponent. +In this way, numbers of any size and with any number of decimal places can be represented exactly. + +```elixir +Decimal.new(_sign = 1, _coefficient = 42, _exponent = 0) #=> Decimal.new("42") +Decimal.new(-1, 42, 0) #=> Decimal.new("-42") +Decimal.new(1, 42, -1) #=> Decimal.new("4.2") +Decimal.new(1, 42, -20) #=> Decimal.new("4.2E-19") +Decimal.new(1, 42, 20) #=> Decimal.new("4.2E+21") +Decimal.new(1, 123456789987654321, -9) #=> Decimal.new("123456789.987654321") +``` + +For calculations, the amount of desired precision - that is, the number of +decimal digits in the coefficient - can be specified. + ## Usage -Add Decimal as a dependency in your `mix.exs` file. +Add Decimal as a dependency in your `mix.exs` file: ```elixir def deps do @@ -14,7 +31,8 @@ def deps do end ``` -After you are done, run `mix deps.get` in your shell to fetch and compile Decimal. Start an interactive Elixir shell with `iex -S mix`. +Next, run `mix deps.get` in your shell to fetch and compile `Decimal`. Start an +interactive Elixir shell with `iex -S mix`: ```elixir iex> alias Decimal, as: D @@ -32,28 +50,30 @@ iex> D.new("0.33") The context specifies the maximum precision of the result of calculations and the rounding algorithm if the result has a higher precision than the specified -maximum. It also holds the list of set of trap enablers and the currently set +maximum. It also holds the list of set of trap enablers and the current set flags. -The context is stored in the process dictionary, this means that you don't have -to pass the context around explicitly and the flags will be updated -automatically. +The context is stored in the process dictionary. You don't have to pass the +context around explicitly and the flags will be updated automatically. The context is accessed with `Decimal.Context.get/0` and set with -`Decimal.Context.set/1`. It can also be temporarily set with +`Decimal.Context.set/1`. It can be set temporarily with `Decimal.Context.with/2`. ```elixir iex> D.Context.get() %Decimal.Context{flags: [:rounded, :inexact], precision: 9, rounding: :half_up, traps: [:invalid_operation, :division_by_zero]} + iex> D.Context.with(%D.Context{precision: 2}, fn -> IO.inspect D.Context.get() end) %Decimal.Context{flags: [], precision: 2, rounding: :half_up, traps: [:invalid_operation, :division_by_zero]} %Decimal.Context{flags: [], precision: 2, rounding: :half_up, traps: [:invalid_operation, :division_by_zero]} + iex> D.Context.set(%D.Context{D.Context.get() | traps: []}) :ok + iex> D.Context.get() %Decimal.Context{flags: [:rounded, :inexact], precision: 9, rounding: :half_up, traps: []} @@ -61,37 +81,44 @@ iex> D.Context.get() ### Precision and rounding -The precision is used to limit the amount of decimal digits in the coefficient: +Use `:precision` option to limit the amount of decimal digits in the +coefficient of any calculation result: ```elixir iex> D.Context.set(%D.Context{D.Context.get() | precision: 9}) :ok + iex> D.div(100, 3) #Decimal<33.3333333> + iex> D.Context.set(%D.Context{D.Context.get() | precision: 2}) :ok + iex> D.div(100, 3) #Decimal<33> ``` -The rounding algorithm specifies how the result of an operation shall be rounded -when it get be represented with the current precision: +The `:rounding` option specifies the algorithm and precision of the rounding +operation: ```elixir iex> D.Context.set(%D.Context{D.Context.get() | rounding: :half_up}) :ok + iex> D.div(31, 2) #Decimal<16> + iex> D.Context.set(%D.Context{D.Context.get() | rounding: :floor}) :ok + iex> D.div(31, 2) #Decimal<15> ``` ### Comparisons -Using compare operators (`<`, `=`, `>`) directly with two decimals may not return -the correct result. Instead use comparison functions. +Using comparison operators (`<`, `=`, `>`) with two or more decimal digits may +not produce accurate result. Instead, use comparison functions. ```elixir iex> D.compare(-1, 0) @@ -109,46 +136,54 @@ true ### Flags and trap enablers -When an exceptional condition is signalled its flag is set in the context and if -if the trap enabler is set `Decimal.Error` will be raised. +When an exceptional condition is signalled, its flag is set in the current +context. `Decimal.Error` will be raised if the trap enabler is set. ```elixir iex> D.Context.set(%D.Context{D.Context.get() | rounding: :floor, precision: 2}) :ok + iex> D.Context.get().traps [:invalid_operation, :division_by_zero] + iex> D.Context.get().flags [] + iex> D.div(31, 2) #Decimal<15> + iex> D.Context.get().flags [:inexact, :rounded] ``` -`:inexact` and `:rounded` were signaled above because the result of the -operation was inexact given the context's precision and had to be rounded to fit -the precision. `Decimal.Error` was not raised because the signals' trap enablers -weren't set. We can, however, set the trap enabler if we what this condition to -raise. +`:inexact` and `:rounded` flag were signalled above because the result of the +operation was inexact given the context's precision and had to be rounded to +fit the precision. `Decimal.Error` was not raised because the signals' trap +enablers weren't set. ```elixir iex> D.Context.set(%D.Context{D.Context.get() | traps: D.Context.get().traps ++ [:inexact]}) :ok + iex> D.div(31, 2) ** (Decimal.Error) ``` -The default trap enablers, such as `:division_by_zero` can be unset: +The default trap enablers, such as `:division_by_zero`, can be unset: ```elixir iex> D.Context.get().traps [:invalid_operation, :division_by_zero] + iex> D.div(42, 0) ** (Decimal.Error) + iex> D.Context.set(%D.Context{D.Context.get() | traps: [], flags: []}) :ok + iex> D.div(42, 0) #Decimal<Infinity> + iex> D.Context.get().flags [:division_by_zero] ``` diff --git a/lib/decimal.ex b/lib/decimal.ex index 10cf59a..cd5cd9e 100644 --- a/lib/decimal.ex +++ b/lib/decimal.ex @@ -122,6 +122,15 @@ defmodule Decimal do @doc """ Returns `true` if number is NaN, otherwise `false`. + + ## Examples + + iex> Decimal.nan?(Decimal.new("NaN")) + true + + iex> Decimal.nan?(Decimal.new(42)) + false + """ @spec nan?(t) :: boolean def nan?(%Decimal{coef: :NaN}), do: true @@ -129,6 +138,18 @@ defmodule Decimal do @doc """ Returns `true` if number is ±Infinity, otherwise `false`. + + ## Examples + + iex> Decimal.inf?(Decimal.new("+Infinity")) + true + + iex> Decimal.inf?(Decimal.new("-Infinity")) + true + + iex> Decimal.inf?(Decimal.new("1.5")) + false + """ @spec inf?(t) :: boolean def inf?(%Decimal{coef: :inf}), do: true @@ -187,6 +208,18 @@ defmodule Decimal do @doc """ The absolute value of given number. Sets the number's sign to positive. + + ## Examples + + iex> Decimal.abs(Decimal.new("1")) + Decimal.new("1") + + iex> Decimal.abs(Decimal.new("-1")) + Decimal.new("1") + + iex> Decimal.abs(Decimal.new("NaN")) + Decimal.new("NaN") + """ @spec abs(t) :: t def abs(%Decimal{coef: :NaN} = num), do: %{num | sign: 1} @@ -203,10 +236,10 @@ defmodule Decimal do ## Examples iex> Decimal.add(1, "1.1") - #Decimal<2.1> + Decimal.new("2.1") iex> Decimal.add(1, "Inf") - #Decimal<Infinity> + Decimal.new("Infinity") """ @spec add(decimal, decimal) :: t @@ -254,10 +287,10 @@ defmodule Decimal do ## Examples iex> Decimal.sub(1, "0.1") - #Decimal<0.9> + Decimal.new("0.9") iex> Decimal.sub(1, "Inf") - #Decimal<-Infinity> + Decimal.new("-Infinity") """ @spec sub(decimal, decimal) :: t @@ -418,10 +451,10 @@ defmodule Decimal do ## Examples iex> Decimal.div(3, 4) - #Decimal<0.75> + Decimal.new("0.75") iex> Decimal.div("Inf", -1) - #Decimal<-Infinity> + Decimal.new("-Infinity") """ @spec div(decimal, decimal) :: t @@ -484,10 +517,10 @@ defmodule Decimal do ## Examples iex> Decimal.div_int(5, 2) - #Decimal<2> + Decimal.new("2") iex> Decimal.div_int("Inf", -1) - #Decimal<-Infinity> + Decimal.new("-Infinity") """ @spec div_int(decimal, decimal) :: t @@ -558,7 +591,7 @@ defmodule Decimal do ## Examples iex> Decimal.rem(5, 2) - #Decimal<1> + Decimal.new("1") """ @spec rem(decimal, decimal) :: t @@ -700,13 +733,13 @@ defmodule Decimal do ## Examples iex> Decimal.max(1, "2.0") - #Decimal<2.0> + Decimal.new("2.0") iex> Decimal.max(1, "NaN") - #Decimal<1> + Decimal.new("1") iex> Decimal.max("NaN", "NaN") - #Decimal<NaN> + Decimal.new("NaN") """ @spec max(decimal, decimal) :: t @@ -749,13 +782,13 @@ defmodule Decimal do ## Examples iex> Decimal.min(1, "2.0") - #Decimal<1> + Decimal.new("1") iex> Decimal.min(1, "NaN") - #Decimal<1> + Decimal.new("1") iex> Decimal.min("NaN", "NaN") - #Decimal<NaN> + Decimal.new("NaN") """ @spec min(decimal, decimal) :: t @@ -796,10 +829,10 @@ defmodule Decimal do ## Examples iex> Decimal.negate(1) - #Decimal<-1> + Decimal.new("-1") iex> Decimal.negate("-Inf") - #Decimal<Infinity> + Decimal.new("Infinity") """ doc_since("1.9.0") @@ -816,7 +849,22 @@ defmodule Decimal do def apply_context(%Decimal{} = num), do: context(num) @doc """ - Check if given number is positive + Returns `true` if given number is positive, otherwise `false`. + + ## Examples + + iex> Decimal.positive?(Decimal.new("42")) + true + + iex> Decimal.positive?(Decimal.new("-42")) + false + + iex> Decimal.positive?(Decimal.new("0")) + false + + iex> Decimal.positive?(Decimal.new("NaN")) + false + """ doc_since("1.5.0") @spec positive?(t) :: boolean @@ -826,7 +874,22 @@ defmodule Decimal do def positive?(%Decimal{sign: 1}), do: true @doc """ - Check if given number is negative + Returns `true` if given number is negative, otherwise `false`. + + ## Examples + + iex> Decimal.negative?(Decimal.new("-42")) + true + + iex> Decimal.negative?(Decimal.new("42")) + false + + iex> Decimal.negative?(Decimal.new("0")) + false + + iex> Decimal.negative?(Decimal.new("NaN")) + false + """ doc_since("1.5.0") @spec negative?(t) :: boolean @@ -846,10 +909,10 @@ defmodule Decimal do ## Examples iex> Decimal.mult("0.5", 3) - #Decimal<1.5> + Decimal.new("1.5") iex> Decimal.mult("Inf", -1) - #Decimal<-Infinity> + Decimal.new("-Infinity") """ @spec mult(decimal, decimal) :: t @@ -893,10 +956,10 @@ defmodule Decimal do ## Examples iex> Decimal.normalize(Decimal.new("1.00")) - #Decimal<1> + Decimal.new("1") iex> Decimal.normalize(Decimal.new("1.01")) - #Decimal<1.01> + Decimal.new("1.01") """ doc_since("1.9.0") @@ -926,10 +989,10 @@ defmodule Decimal do ## Examples iex> Decimal.round("1.234") - #Decimal<1> + Decimal.new("1") iex> Decimal.round("1.234", 1) - #Decimal<1.2> + Decimal.new("1.2") """ @spec round(decimal, integer, rounding) :: t @@ -957,7 +1020,7 @@ defmodule Decimal do ## Examples iex> Decimal.sqrt("100") - #Decimal<10> + Decimal.new("10") """ doc_since("1.7.0") @@ -1074,10 +1137,11 @@ defmodule Decimal do ## Examples iex> Decimal.new(1) - #Decimal<1> + Decimal.new("1") iex> Decimal.new("3.14") - #Decimal<3.14> + Decimal.new("3.14") + """ @spec new(decimal) :: t def new(%Decimal{sign: sign, coef: coef, exp: exp} = num) @@ -1101,8 +1165,14 @@ defmodule Decimal do A decimal number will always be created exactly as specified with all digits kept - it will not be rounded with the context. + + ## Examples + + iex> Decimal.new(1, 42, 0) + Decimal.new("42") + """ - @spec new(1 | -1, non_neg_integer | :NaN | :inf, integer) :: t + @spec new(sign :: 1 | -1, coef :: non_neg_integer | :NaN | :inf, exp :: integer) :: t def new(sign, coef, exp) when sign in [1, -1] and ((is_integer(coef) and coef >= 0) or coef in [:NaN, :inf]) and is_integer(exp), @@ -1123,14 +1193,14 @@ defmodule Decimal do 0.30000000000000004 iex> Enum.reduce([Decimal.new("0.1"), Decimal.new("0.1"), Decimal.new("0.1")], &Decimal.add/2) - #Decimal<0.3> + Decimal.new("0.3") For this reason, it's recommended to build decimals with `new/1`, which is always precise, instead. ## Examples iex> Decimal.from_float(3.14) - #Decimal<3.14> + Decimal.new("3.14") """ doc_since("1.5.0") @@ -1154,7 +1224,7 @@ defmodule Decimal do iex> {:ok, decimal} = Decimal.cast(3) iex> decimal - #Decimal<3> + Decimal.new("3") iex> Decimal.cast("bad") :error @@ -1221,6 +1291,23 @@ defmodule Decimal do * `:xsd` - number converted to the [canonical XSD representation](https://www.w3.org/TR/xmlschema-2/#decimal). * `:raw` - number converted to its raw, internal format. + ## Examples + + iex> Decimal.to_string(Decimal.new("1.00")) + "1.00" + + iex> Decimal.to_string(Decimal.new("123e1"), :scientific) + "1.23E+3" + + iex> Decimal.to_string(Decimal.new("42.42"), :normal) + "42.42" + + iex> Decimal.to_string(Decimal.new("1.00"), :xsd) + "1.0" + + iex> Decimal.to_string(Decimal.new("4321.768"), :raw) + "4321768E-3" + """ @spec to_string(t, :scientific | :normal | :xsd | :raw) :: String.t() def to_string(num, type \\ :scientific) @@ -1317,6 +1404,18 @@ defmodule Decimal do Returns the decimal represented as an integer. Fails when loss of precision will occur. + + ## Examples + + iex> Decimal.to_integer(Decimal.new("42")) + 42 + + iex> Decimal.to_integer(Decimal.new("1.00")) + 1 + + iex> Decimal.to_integer(Decimal.new("1.10")) + ** (ArgumentError) cannot convert Decimal.new("1.1") without losing precision. Use Decimal.round/3 first. + """ @spec to_integer(t) :: integer def to_integer(%Decimal{sign: sign, coef: coef, exp: 0}) @@ -1331,11 +1430,22 @@ defmodule Decimal do when is_integer(coef) and exp < 0 and Kernel.rem(coef, 10) == 0, do: to_integer(%Decimal{sign: sign, coef: Kernel.div(coef, 10), exp: exp + 1}) + def to_integer(%Decimal{coef: coef} = decimal) when is_integer(coef) do + raise ArgumentError, + "cannot convert #{inspect(decimal)} without losing precision. Use Decimal.round/3 first." + end + @doc """ Returns the decimal converted to a float. The returned float may have lower precision than the decimal. Fails if the decimal cannot be converted to a float. + + ## Examples + + iex> Decimal.to_float(Decimal.new("1.5")) + 1.5 + """ @spec to_float(t) :: float def to_float(%Decimal{sign: sign, coef: coef, exp: exp}) when is_integer(coef) do @@ -1359,6 +1469,29 @@ defmodule Decimal do end end + @doc """ + Returns the scale of the decimal. + + A decimal's scale is the number of digits after the decimal point. This + includes trailing zeros; see `normalize/1` to remove them. + + ## Examples + + iex> Decimal.scale(Decimal.new("42")) + 0 + + iex> Decimal.scale(Decimal.new(1, 2, 26)) + 0 + + iex> Decimal.scale(Decimal.new("99.12345")) + 5 + + iex> Decimal.scale(Decimal.new("1.50")) + 2 + """ + @spec scale(t) :: non_neg_integer() + def scale(%Decimal{exp: exp}), do: Kernel.max(0, -exp) + defp scale_up(num, den, exp) when num >= den, do: {num, exp} defp scale_up(num, den, exp), do: scale_up(num <<< 1, den, exp - 1) @@ -1401,9 +1534,10 @@ defmodule Decimal do iex> Decimal.integer?("1.10") false + """ doc_since("2.0.0") - @spec integer?(t) :: boolean + @spec integer?(decimal()) :: boolean def integer?(%Decimal{coef: :NaN}), do: false def integer?(%Decimal{coef: :inf}), do: false def integer?(%Decimal{coef: coef, exp: exp}), do: exp >= 0 or zero_after_dot?(coef, exp) @@ -1412,8 +1546,8 @@ defmodule Decimal do defp zero_after_dot?(coef, exp) when coef >= 10 and exp < 0, do: Kernel.rem(coef, 10) == 0 and zero_after_dot?(Kernel.div(coef, 10), exp + 1) - defp zero_after_dot?(_coef, exp), - do: exp == 0 + defp zero_after_dot?(coef, exp), + do: coef == 0 or exp == 0 ## ARITHMETIC ## @@ -1774,7 +1908,7 @@ end defimpl Inspect, for: Decimal do def inspect(dec, _opts) do - "#Decimal<" <> Decimal.to_string(dec) <> ">" + "Decimal.new(\"" <> Decimal.to_string(dec) <> "\")" end end diff --git a/mix.exs b/mix.exs index aeca126..c342634 100644 --- a/mix.exs +++ b/mix.exs @@ -24,7 +24,7 @@ defmodule Decimal.Mixfile do defp deps() do [ - {:ex_doc, ">= 0.0.0", only: :dev} + {:ex_doc, ">= 0.0.0", only: :dev, runtime: false} ] end diff --git a/mix.lock b/mix.lock index 1055260..acc881f 100644 --- a/mix.lock +++ b/mix.lock @@ -1,7 +1,8 @@ %{ - "earmark_parser": {:hex, :earmark_parser, "1.4.10", "6603d7a603b9c18d3d20db69921527f82ef09990885ed7525003c7fe7dc86c56", [:mix], [], "hexpm", "8e2d5370b732385db2c9b22215c3f59c84ac7dda7ed7e544d7c459496ae519c0"}, - "ex_doc": {:hex, :ex_doc, "0.22.2", "03a2a58bdd2ba0d83d004507c4ee113b9c521956938298eba16e55cc4aba4a6c", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "cf60e1b3e2efe317095b6bb79651f83a2c1b3edcb4d319c421d7fcda8b3aff26"}, - "makeup": {:hex, :makeup, "1.0.3", "e339e2f766d12e7260e6672dd4047405963c5ec99661abdc432e6ec67d29ef95", [:mix], [{:nimble_parsec, "~> 0.5", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "2e9b4996d11832947731f7608fed7ad2f9443011b3b479ae288011265cdd3dad"}, - "makeup_elixir": {:hex, :makeup_elixir, "0.14.1", "4f0e96847c63c17841d42c08107405a005a2680eb9c7ccadfd757bd31dabccfb", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f2438b1a80eaec9ede832b5c41cd4f373b38fd7aa33e3b22d9db79e640cbde11"}, - "nimble_parsec": {:hex, :nimble_parsec, "0.6.0", "32111b3bf39137144abd7ba1cce0914533b2d16ef35e8abc5ec8be6122944263", [:mix], [], "hexpm", "27eac315a94909d4dc68bc07a4a83e06c8379237c5ea528a9acff4ca1c873c52"}, + "earmark_parser": {:hex, :earmark_parser, "1.4.25", "2024618731c55ebfcc5439d756852ec4e85978a39d0d58593763924d9a15916f", [:mix], [], "hexpm", "56749c5e1c59447f7b7a23ddb235e4b3defe276afc220a6227237f3efe83f51e"}, + "ex_doc": {:hex, :ex_doc, "0.28.3", "6eea2f69995f5fba94cd6dd398df369fe4e777a47cd887714a0976930615c9e6", [:mix], [{:earmark_parser, "~> 1.4.19", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "05387a6a2655b5f9820f3f627450ed20b4325c25977b2ee69bed90af6688e718"}, + "makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"}, + "makeup_elixir": {:hex, :makeup_elixir, "0.16.0", "f8c570a0d33f8039513fbccaf7108c5d750f47d8defd44088371191b76492b0b", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "28b2cbdc13960a46ae9a8858c4bebdec3c9a6d7b4b9e7f4ed1502f8159f338e7"}, + "makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"}, + "nimble_parsec": {:hex, :nimble_parsec, "1.2.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"}, } diff --git a/test/decimal_test.exs b/test/decimal_test.exs index 1be7c51..f2cc999 100644 --- a/test/decimal_test.exs +++ b/test/decimal_test.exs @@ -596,9 +596,11 @@ defmodule DecimalTest do assert Decimal.to_integer(d(1, 1_365_900_000_000_000_000_000, -2)) == 13_659_000_000_000_000_000 - assert_raise FunctionClauseError, fn -> - Decimal.to_integer(d(1, 1001, -2)) - end + assert_raise( + ArgumentError, + "cannot convert Decimal.new(\"10.01\") without losing precision. Use Decimal.round/3 first.", + fn -> Decimal.to_integer(d(1, 1001, -2)) end + ) assert_raise FunctionClauseError, fn -> Decimal.to_integer(d(1, :NaN, 0)) @@ -755,6 +757,8 @@ defmodule DecimalTest do assert Decimal.integer?(~d"1e100") assert Decimal.integer?(~d"1.23e5") assert Decimal.integer?(~d"10000e-3") + assert Decimal.integer?(~d"0.0") + assert Decimal.integer?(~d"1.0") refute Decimal.integer?(~d"0.1") refute Decimal.integer?(~d"0.10")
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor