0

Elixir 默认使用科学记数法表示大于 1000 的浮点数。这会在 json 序列化过程中产生不希望的副作用。

iex(5)> val = 1000.00
1.0e3
iex(11)> Poison.encode(val)
{:ok, "1.0e3"}

我想要的输出是

iex(11)> Poison.encode(val)
{:ok, "1000.00"}

我已经看到使用or的这个答案,但这需要在编码之前修补或手动检查所有数据。:erlang.float_to_binary(0.005 * 2.7 / 100, [:compact, {:decimals, 10}]):io.format("~f~n",[0.005 * 2.7 / 100])Poison

有没有一种更简洁的方法可以强制在 elixir 中将默认浮点数转换为二进制格式?

4

1 回答 1

2

Poison允许实现Poison.Encoder协议。Float显然存在的实现,这就是为什么我建议将您的浮动包装到自定义的FloatStruct前期:

defmodule FloatStruct do
  defstruct value: 0.0, format: [:compact, {:decimals, 10}]
end

defimpl Poison.Encoder, for: FloatStruct do
  def encode(%{value: value, format: format}, options) do
    Poison.Encoder.BitString.encode(
      :erlang.float_to_binary(value, format), options)
  end
end

我知道这需要遍历嵌套术语来Float用 s 包装 s FloatStruct,但我没有看到任何更简单的方法。不过,我可能是错的。


可以免费支持 OP 格式中提到的两种:

defimpl Poison.Encoder, for: FloatStruct do
  def encode(%{value: value, format: format}, options) do
    Poison.Encoder.BitString.encode(
      format(value, format), options)
  end

  defp format(value, format) when is_list(format),
    do: :erlang.float_to_binary(value, format)
  defp format(value, format) when is_binary(format),
    do: :io.format(format, [value])
end
于 2018-03-15T10:06:27.397 回答