json 在 elixir 中序列化时的浮点格式
Float format when json serializing in elixir
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])
,但这需要修补 Poison
或在编码前手动检查所有数据。
在 elixir 中是否有更简洁的方法强制默认 flot 为二进制格式?
Poison
允许实现 Poison.Encoder
protocol. The implementation for Float
obviously 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
我知道这需要遍历嵌套的术语来用 FloatStruct
包装 Float
,但我没有看到任何更简单的方法。不过我可能是错的。
有人可能会免费支持 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
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])
,但这需要修补 Poison
或在编码前手动检查所有数据。
在 elixir 中是否有更简洁的方法强制默认 flot 为二进制格式?
Poison
允许实现 Poison.Encoder
protocol. The implementation for Float
obviously 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
我知道这需要遍历嵌套的术语来用 FloatStruct
包装 Float
,但我没有看到任何更简单的方法。不过我可能是错的。
有人可能会免费支持 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