根据手数计算数量

问题描述 投票:0回答:2

我有这个代码和测试:

  def order_quantity(:sell, free_quantity, lot_step_size, quantity_precision) do
    {q, _} = :erlang.float_to_binary(Float.floor(free_quantity / lot_step_size) * lot_step_size, decimals: quantity_precision) |> Float.parse()
    q
  end

assert order_quantity(:sell, 0.01977578, 0.00010000, 8) == 0.0197
assert order_quantity(:sell, 0.290709, 0.00100000, 8) == 0.29000000
assert order_quantity(:sell, 111.88800000, 0.01000000, 8) == 111.88

但我对此并不满意——有没有更像 Elixir 的方法来完成相同的计算?

elixir
2个回答
1
投票

Float.floor/2
是你的朋友。

iex|1▸ Float.floor 0.01977578, 4
0.0197
iex|2▸ Float.floor 0.290709, 3
0.29
iex|3▸ Float.floor 111.88800000, 2
111.88

此外,您可能最好重新考虑如何通过

free_quantity
。将其作为整数传递可能更有意义,而不是不一定精确浮点数。


1
投票

如果你关心精度,你应该使用

:decimal
库。 https://hexdocs.pm/decimal/Decimal.html

有了这个你可以简单地做:

iex> Decimal.round("0.01977578", 4, :down)
#Decimal<0.0197>

第一个参数是浮点数或字符串,第二个参数是小数位数,第三个参数是舍入“模式”。

您的主要问题是如何从

lot_step_size
浮点数中获取小数位数(整数)。

你可以创建一个函数来计算

places
从任何给定的手步长,但如果你知道这些只到,比如说,小数点后 8 位,那么你可以为每个写一个更有效(更快)的“模式”,如下所示:

  def places(0.00000001), do: 8
  def places(0.0000001), do: 7
  def places(0.000001), do: 6
  def places(0.00001), do: 5
  def places(0.0001), do: 4
  def places(0.001), do: 3
  def places(0.01), do: 2
  def places(0.1), do: 1

  def order_quantity(:sell, free_quantity, lot_step_size) do
    free_quantity
    |> to_string()
    |> Decimal.round(places(lot_step_size), :down)
    |> Decimal.to_float()
  end

请注意,我在完成后转换回浮点数,但你最好在所有地方使用 Decimal 并避免浮点数。

© www.soinside.com 2019 - 2024. All rights reserved.