判断整数是偶数还是奇数

Finding if Integer is Even or Odd

我正在学习 Erlang 并且 Joe 书中提到的问题之一

The function even(X) should return true if X is an even integer and otherwise false. odd(X) should return true if X is an odd integer.

我解决这个问题的方法是

-module(math_functions).

%% API
-export([even/1, odd/1]).

even(Integer) -> (Integer >= 0) and (Integer rem 2 =:= 0).
odd(Integer) -> (Integer >= 1) and (Integer rem 2 =/= 0).

并将其作为

运行
Eshell V6.2  (abort with ^G)
1> math_functions:odd(13).
true
2> math_functions:odd(-13).
false
3> math_functions:odd(1).
true
4> math_functions:even(1).
false
5> math_functions:even(2).
true
6> math_functions:even(-2).
false
7>   

我的问题是是否有更好的方法来做到这一点

谢谢

您可以使用守卫将自己限制为大于或等于零的整数,然后按照问题评论中的建议简单地检查最低有效位。您还可以根据 even/1:

定义 odd/1
even(X) when X >= 0 -> (X band 1) == 0.
odd(X) when X > 0 -> not even(X).

守卫是函数头的一部分,所以如果你调用 even(-1) 它将无法匹配,就像你调用 even(1, 2) 一样(即错误的数量参数)。

对 Daydreamer 关于史蒂夫回答的评论的回答。

当你写一个函数时,erlang 中的一个常见用法是只编写 "success" 案例,让不成功的案例崩溃(稍后我会回来解释为什么它很重要)。

另一个适用于任何语言的标准是避免有人在使用或阅读您的代码时感到意外。

在你的一个评论中你说你想写的奇数和偶数函数被限制为正整数或空整数(我不会讨论这个选择,至少奇数和偶数函数被限制为整数).这意味着您必须问自己第一个问题:如果使用错误参数调用我的函数,它的行为是什么。

第一选择:让它崩溃 这是 Steve 的命题:函数只在正确的参数下工作。我总是喜欢这个解决方案。唯一的例外是如果我不掌握输入参数,例如如果它们直接来自文件,用户界面......那么我更喜欢第三种选择。

第二个选择:return一个结果这是你的选择:你return错了。从逻辑的角度来看,对于奇数和偶数函数,returning false 是有效的:如果某事不正确,则为 false :o)。我不喜欢这个解决方案有两个原因。第一个是它不是你可以轻易概括为布尔答案以外的东西。第二个对我来说更重要的是,它可能会让用户感到惊讶。当函数 odd(N) return false 时,认为 N 是偶数是合理的,而在这种情况下 odd(-2) 和 even(-2) 都将 return false.

第三选择:return 一个标记结果 这是你在 erlang 中经常看到的东西:一个函数 return {ok,Value} 或{错误,术语}。这样做你可以选择调用函数来管理或不管理错误的参数错误。 Error 变量允许您有明确的错误消息,对调试和用户界面很有用。在您的示例中,代码变为:

even(X) when is_integer(X), X >= 0 -> {ok,(X band 1) == 0};
even(X) -> {illegal_param,X}.
odd(X) when is_integer(X), X >= 0 -> {ok,(X band 1) == 1};
odd(X) -> {illegal_param,X}.

编程时,尽快发现错误很重要,在erlang中更重要。如果一个进程没有检测(最简单的检测是崩溃)和错误并通过消息传播一些无效信息,则可能很难找到问题的根本原因,忽略哪个进程(可能已死亡)发出此消息。仅对成功案例进行编码是尽快发现问题的简单方法。

Find the no if even 
%functions that manipulate functions are called higher-order %functions, and the data type that represents a function in Erlang is %called a fun. here in below example you see FUNCTIONS THAT HAVE %FUNCTIONS AS THEIR ARGUMENTS

% K is an example list
1> K=[4,5,6,8,10].  
[4,5,6,8,10]

% Use lisst:filter  to perform no/2  and filter if rem=0 
2> lists:filter(fun(J)->(J rem 2)=:=0 end, K).
[4,6,8,10]


Another way:

% Function to check even

22> Checkeven=fun(U)->(U rem 2)=:=0 end. 
#Fun<erl_eval.7.126501267>

23> Checkeven(5).
false

% Define a test list
25> K=[1,2,3,4,5].
[1,2,3,4,5]

% Use lists filter to apply Checkeven func to all elements of k

26> lists:filter(Checkeven,K). 

[2,4]


%Using List comprehension

42> K.
[1,2,3,4,5]

% For all elements of K check remainder of elem/2 is zero

43> [(S rem 2=:=0) || S<-K].
[false,true,false,true,false]