【问题标题】:How do I raise a number to a power in Elixir?如何在 Elixir 中将数字提升为幂?
【发布时间】:2015-08-15 11:13:59
【问题描述】:

如何在 Elixir 中计算具有指数的数字?

例如,23 将返回 8。

【问题讨论】:

    标签: elixir


    【解决方案1】:

    使用Erlang :math module

    :math.pow(2,3) #=> 8.0
    

    如果你想要一个整数:

    :math.pow(2,3) |> round #=> 8
    

    【讨论】:

      【解决方案2】:

      Erlang 的:math.pow 有一些限制,例如它不允许使用非常高的整数指数:

      iex(10)> :math.pow(2, 10000)
      ** (ArithmeticError) bad argument in arithmetic expression
      

      您可以轻松地重新实现一个快速算法来计算指数,该算法适用于运行时提供的任意大整数:

      defmodule Pow do
        require Integer
      
        def pow(_, 0), do: 1
        def pow(x, n) when Integer.is_odd(n), do: x * pow(x, n - 1)
        def pow(x, n) do
          result = pow(x, div(n, 2))
          result * result
        end
      end
      
      iex(9)> Pow.pow(2, 10000)
      19950631168807583848837421626835850838234968318861924548520089498529438830...
      

      【讨论】:

        【解决方案3】:

        这里是幂函数的尾调用优化实现:

        def  pow(n, k), do: pow(n, k, 1)        
        defp pow(_, 0, acc), do: acc
        defp pow(n, k, acc), do: pow(n, k - 1, n * acc)
        

        【讨论】:

        • 非常好!将:math.pow 的当前实现替换为对此的 Erlang 翻译会很好。 github.com/erlang/otp
        【解决方案4】:

        整数.pow/2

        从 v1.12 开始,Integer.pow/2 是执行此操作的方法。

        【讨论】:

        • 对于分数基数/幂,您仍然必须使用 :math.pow/2
        【解决方案5】:

        **/2

        从 Elixir 1.13 开始,** 可用。

        > 2 ** 3 
        8
        

        注意:如果指数小于 0,则返回浮点数。

        Documentation

        【讨论】:

        • 我不确定它是否有效,因为我收到一个错误 -> (SyntaxError) iex:3:4: syntax error before: '*'
        • 嗨@Borybar。您能否确认您使用的是什么版本的 Elixir?我刚刚尝试使用 1.13 候选版本 (1.13.0-rc.0) 并收到以下信息:> elixir -v Elixir 1.13.0-rc.0 (5062a15) (compiled with Erlang/OTP 22) 和 iex 控制台:iex(1)> 2 ** 4 输出 16
        • 我使用的是 Elixir 1.12.2,所以我猜是旧版本。但是,我认为它现在也不适用于您,所以我认为它与某个版本相关联是否正确?
        • 不幸的是这种情况。它是在最新版本中添加的。 changelog。如果您使用的是 ~1.12,则此页面上的其他解决方案就足够了。
        【解决方案6】:

        如果底数是 2 并且幂是整数,您可以使用函数 Bitwise.bsl 进行左位移。例如,23 可以这样计算:

        > Bitwise.bsl(1, 3)
        8
        

        【讨论】:

          【解决方案7】:

          这是有效的——当我学到足够多的知识来确切地知道它为什么有效时会很棒——可能与幕后的 eval 有关:

          defmodule Example do
            require Integer
          
            def do_it(list) do
              list
              |> Enum.reject(&Integer.is_odd(&1))
              |> Enum.map(&(:math.pow(&1,3)))
            end
          
          end
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2018-12-14
            • 1970-01-01
            • 2018-04-21
            • 1970-01-01
            • 1970-01-01
            • 2022-11-11
            • 1970-01-01
            相关资源
            最近更新 更多