我不知道这是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,那就好了。
答案 0 :(得分:2)
Elixir对Inspect
just delegates to :io_lib_format.fwrite_g/1
和:io_lib_format.fwrite_g/1
's source in Erlang/OTP的Float
实施提到它尝试以尽可能少的字符准确打印数字。因此,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。