2017-06-08 11 views
0

I持っている唯一のn 2つの整数(1, 2, 4, 8, 16, 32, 64, ...)の電源であるの値と一致する必要が次の関数:ガード句の場合、エリクサーでビット演算子を使用する方法は?

defmodule MyModule do 
    def my_func(n) when is_power_of_two(n) do 
    ## Some expression 
    end 
    def is_power_of_two(x) do 
    (x != 0) 
     and (x &&& (x - 1)) == 0) 
    end 
end 

まず、「私は、モジュール内の関数としてis_power_of_twoを定義しようとしたが、それはなかったの私はこのエラーを受けました:

cannot invoke local is_power_of_two/1 inside guard

このblog postに続いて、私は次のマクロとしてそれを定義しようとしました:

defmodule MyModule.Util do 
    defmacro is_power_of_two(x) do 
    quote do 
     (unquote(x) != 0) 
     and ((unquote(x) &&& (unquote(x) - 1)) == 0) 
    end 
    end 
end 

は同様に動作しませんでしたし、私は次のエラーを取得:

cannot invoke local &&&/2 inside guard

をそれはと思われますマクロ展開後にビット単位で&&&演算子をwhen句から呼び出すことはできません。

ビット演算子を含むガードが必要な一致を実行するにはどうすればよいですか?

答えて

2

エラーメッセージは誤解を招く可能性があります。ちょうどimport BitwiseMyModule.Utilにありません。

defmodule MyModule.Util do 
    import Bitwise 

    defmacro is_power_of_two(x) do 
    quote do 
     (unquote(x) != 0) and ((unquote(x) &&& (unquote(x) - 1)) == 0) 
    end 
    end 
end 

defmodule MyModule do 
    import MyModule.Util 

    def my_func(n) when is_power_of_two(n) do 
    true 
    end 
    def my_func(_), do: false 
end 

IO.inspect MyModule.my_func(128) 
IO.inspect MyModule.my_func(129) 

出力:

true 
false 
私は importを追加する場合のコードは動作します
関連する問題