【问题标题】:Ecto returns numbers in scientific (exponential) notationEcto 以科学(指数)表示法返回数字
【发布时间】:2016-08-06 04:11:41
【问题描述】:

我不知道是 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 手动更改为 FLOAT,问题仍然存在。但是如果我把它改成INTEGER就好了。

【问题讨论】:

  • 您在迁移表和模型中的模式声明时为该列使用了什么类型?您能否在问题中包含这两个文件的相关 sn-ps?
  • @Dogbert 我更新了我的问题
  • 所以-也许这是一个愚蠢的问题-为什么要将整数保留为浮点数?只需在架构中使用整数。
  • @PatNowak 这只是一个例子。当我第一次遇到这个问题时,我通过将 Float 转换为 Money 来解决这个问题,但现在我必须使用 Float。

标签: elixir ecto


【解决方案1】:

Elixir 对Float just delegates to :io_lib_format.fwrite_g/1:io_lib_format.fwrite_g/1's source in Erlang/OTPInspect 实现提到它试图以尽可能少的字符数准确地打印数字。所以,1000 被转换为1.0e3,因为它比1000.0 短,但100.0 没有被转换为1.0e2,因为它不短于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]

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

【讨论】:

    【解决方案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。

    【讨论】:

      猜你喜欢
      • 2012-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-18
      相关资源
      最近更新 更多