与Decimal或Money库一起使用

时间:2018-05-02 18:07:59

标签: elixir decimal

我需要一个函数,它取一个十进制(它的钱,所以两个小数位)并舍入到最接近的四分之一。我试图避免转换为浮点数并保持在十进制世界中。 (我也查看了Money库,但没有看到能够满足我需要的舍入函数。

此功能有效,但很可怕。十进制库本身只支持舍入到整数或一半,我不能将值如:lt和gt转换为Enum.member?因为它们不是可枚举的,所以我使用了单独的条件:lt和:gt。

  def round_up_to_nearest_quarter(preroundedamount) do
    alias Decimal, as: D

    base = D.round(preroundedamount, 0, :floor)
    frac = D.sub(preroundedamount, base)

    newfrac =
      cond do
        D.cmp(frac, 0) == :eq ->
          D.new("0.0")

        D.cmp(frac, D.new("0.25")) == :lt ->
          D.new("0.25")

        D.cmp(frac, D.new("0.25")) == :eq ->
          D.new("0.25")

        D.cmp(frac, D.new("0.5")) == :lt ->
          D.new("0.5")

        D.cmp(frac, D.new("0.5")) == :eq ->
          D.new("0.5")

        D.cmp(frac, D.new("0.75")) == :lt ->
          D.new("0.75")

        D.cmp(frac, D.new("0.75")) == :eq ->
          D.new("0.75")

        D.cmp(frac, D.new("1.0")) == :lt ->
          D.new("1.0")

        D.cmp(frac, D.new("1.0")) == :eq ->
          D.new("1.0")

        true ->
          D.new("0.0")
      end

    D.add(base, newfrac)
  end

最长的Elixir-ian **方式是什么?

**另外,“Elixir”的形容词形式是什么?寻找类似“Pythonic”的东西。

1 个答案:

答案 0 :(得分:3)

要向上舍入到最接近的0.25的倍数,您可以将数字乘以4,进行正常的向上舍入,然后将其除以4:

rounded = n |> Decimal.mult(4) |> Decimal.round(0, :up) |> Decimal.div(4)

测试:

for i <- 1..25 do
  # 0.1, 0.2, ..., 2.5
  n = Decimal.new(i) |> Decimal.div(Decimal.new(10))
  rounded = n |> Decimal.mult(4) |> Decimal.round(0, :up) |> Decimal.div(4)
  IO.inspect {Decimal.to_string(n), Decimal.to_string(rounded)}
end

输出:

{"0.1", "0.25"}
{"0.2", "0.25"}
{"0.3", "0.5"}
{"0.4", "0.5"}
{"0.5", "0.5"}
{"0.6", "0.75"}
{"0.7", "0.75"}
{"0.8", "1"}
{"0.9", "1"}
{"1", "1"}
{"1.1", "1.25"}
{"1.2", "1.25"}
{"1.3", "1.5"}
{"1.4", "1.5"}
{"1.5", "1.5"}
{"1.6", "1.75"}
{"1.7", "1.75"}
{"1.8", "2"}
{"1.9", "2"}
{"2", "2"}
{"2.1", "2.25"}
{"2.2", "2.25"}
{"2.3", "2.5"}
{"2.4", "2.5"}
{"2.5", "2.5"}