Ecto以科学(指数)表示法返回数字

时间:2016-08-05 10:39:58

标签: elixir ecto

我不知道这是Ecto还是Elixir的问题。当我在数据库中有一个数字,如1000,15000等.Ecto将其返回为1.0e3,1.5e4 ......如果我将1000更改为1234,一切正常。

Elixir 1.3.2,Ecto 2.0.3,MySQL

迁移:

alter table(:incoming_transfers) do
  add :fee, :float # Ecto translates it as DOUBLE in MySQL
end

架构:

schema "incoming_transfers" do
  field :fee, :float
end

如果我在数据库中手动更改类型DOUBLE to FLOAT,问题仍然存在。但如果我把它改成INTEGER,那就好了。

2 个答案:

答案 0 :(得分:2)

Elixir对Inspect just delegates to :io_lib_format.fwrite_g/1:io_lib_format.fwrite_g/1's source in Erlang/OTPFloat实施提到它尝试以尽可能少的字符准确打印数字。因此,1000转换为1.0e3,因为它比1000.0短,但100.0未转换为1.0e2,因为“{1}}不短于100.0。同样,12300.0会转换为1.23e4,因为它会更短。

%%  Writes the shortest, correctly rounded string that converts
%%  to Float when read back with list_to_float/1.
%%
%%  See also "Printing Floating-Point Numbers Quickly and Accurately"
%%  in Proceedings of the SIGPLAN '96 Conference on Programming
%%  Language Design and Implementation.

二郎:

1> [1000.0, 100.0, 12300.0].
[1.0e3,100.0,1.23e4]

请注意,这 not 会导致失去任何准确性(超出已经失去的浮动数字)。 1000.0完全等于1.0e3

答案 1 :(得分:2)

对于想要覆盖@Dogbert提到的功能的人。把它放在你的代码中:

defimpl Inspect, for: Float do
  def inspect(term, _opts) do
    IO.iodata_to_binary(:io_lib_format.fwrite_g(term))
  end
end

并将:io_lib_format.fwrite_g(term)更改为:erlang. float_to_binary(term, [decimals: 6])之类的内容。 例如,对于7.12,它会返回"7.120000"

无论如何,我认为最好使用Decimal而不是Float。