Current section

Files

Jump to
vtc lib utils_rational.ex
Raw

lib/utils_rational.ex

defmodule Vtc.Utils.Rational do
@moduledoc """
Helper functions and types for working with the Ratio module.
"""
@typedoc """
The Ratio module will often convert itself to an integer value if the result would be
a whole number, but otherwise return a %Ratio{} struct.
This type can be used when working with such a value.
"""
@type t() :: Ratio.t() | integer()
@doc """
Rounds a Ratio to the nearest integer.
"""
@spec round(t()) :: integer()
def round(x) when is_integer(x), do: x
def round(%Ratio{} = x) do
floored = Ratio.floor(x)
remainder = Ratio.sub(x, floored)
case Ratio.compare(remainder, Ratio.new(1, 2)) do
:gt -> Ratio.add(floored, 1)
_ -> floored
end
end
@doc """
Does the divmod operation on a rational vale, returns a
{whole_dividend, rational_rainder} tuple.
"""
@spec divmod(t(), t()) :: {integer(), t()}
def divmod(a, b) do
dividend = a |> Ratio.div(b) |> Ratio.floor()
multiplied = Ratio.mult(dividend, b)
remainder = Ratio.sub(a, multiplied)
{dividend, remainder}
end
end