当json在elixir中序列化时的浮点格式

时间:2018-03-15 09:56:35

标签: json elixir elixir-poison

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"}

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

是否有更简洁的方法可以将默认flot强制为elixir中的二进制格式?

1 个答案:

答案 0 :(得分:2)

Poison允许实施Poison.Encoder协议。 Float的实现显然exists,这就是为什么我建议将你的花车自动包装到自定义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包裹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