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中的二进制格式?
答案 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