given any number, what's the best way to determine it is even? how many methods can you think of, and what is the fastest way and clearest way?
views:
694answers:
18how many ways are there to see if a number is even, and which one is the fastest and clearest?
You can either using integer division and divide it by two and inspect the remainder or use a modulus operator and mod it by two and inspect the remainder. The "fastest" way depends on the language, compiler, and other factors but I doubt there are many platforms for which there is a significant difference.
bool isEven = ((number & 0x01) == 0)
The question said "any number", so one could either discard floats or handle them in another manner, perhaps by first scaling them up to an integral value first - watching out for overflow - i.e. change 2.1 to 21 (multiply by 10 and convert to int) and then test. It may be reasonable to assume, however, that by mentioning "any number" the person who posed the question is actually referring to integral values.
Yes.. The fastest way is to check the 1 bit, because it is set for all odd numbers and unset for all even numbers..
Bitwise ANDs are pretty fast.
If your type 'a' is an integral type, then we can define,
even :: Integral a => a -> Bool
even n = n `rem` 2 == 0
according to the Haskell Prelude.
isEven(n) = ((-1) ^ n) == 1
where ^ is the exponentiation/pow function of your language.
I didn't say it was fast or clear, but it has novelty value.
For floating points, of course within a reasonable bound.
modf(n/2.0, &intpart, &fracpart)
return fracpart == 0.0
With some other random math functions:
return gcd(n,2) == 2
return lcm(n,2) == n
return cos(n*pi) == 1.0
If it's low level check if the last (LSB) bit is 0 or 1 :)
0 = Even
1 = Odd
Otherwise, +1 @sipwiz: "bool isEven = number % 2 == 0;"
Assumming that you are dealing with an integer, the following will work:
if ((testnumber & -2)==testnumber) then testnumber is even.
basically, -2 in hex will be FFFE (for 16 bits) if the number is even, then anding with with -2 will leave it unchanged. ** Tom **
With reservations for limited stack space. ;) (Is this perhaps a candidate for tail calls?)
public static bool IsEven(int num) {
if (num < 0)
return !IsEven(-num - 1);
if (num == 0)
return true;
return IsEven(-num);
}
Actually I think (n % 2 == 0) is enough, which is easy to understand and most compilers will convert it to bit operations as well.
I compiled this program with gcc -O2 flag:
#include <stdio.h>
int main()
{
volatile int x = 310;
printf("%d\n", x % 2);
return 0;
}
and the generated assembly code is
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $32, %esp
movl $310, 28(%esp)
movl 28(%esp), %eax
movl $.LC0, (%esp)
movl %eax, %edx
shrl $31, %edx
addl %edx, %eax
andl $1, %eax
subl %edx, %eax
movl %eax, 4(%esp)
call printf
xorl %eax, %eax
leave
ret
which we can see that % 2 operation is already converted to the andl instruction.
Similar to DeadHead's comment, but more efficient:
#include <limits.h>
bool isEven(int num)
{
bool arr[UINT_MAX] = { 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
// ...and so on
};
return arr[num];
}
As fast as an array index, which may or may not be faster than bitwise computations (it's difficult to test because I don't want to write the full version of this function). For what it's worth, that function above only has enough filled in to find even numbers up to 442, but would have to go to 4294967295 to work on my system.
Recursion!
function is_even (n number) returns boolean is
if n = 0 then
return true
elsif n = 1 then
return false
elsif n < 0 then
return is_even(n * -1)
else
return is_even(n - 2)
end if
end
Continuing the spirit of "how many ways are there...":
function is_even (n positive_integer) returns boolean is
i := 0
j := 0
loop
if n = i then
return (j = 0)
end if;
i := i + 1
j := 1 - j
end loop
end
The answer depends on the position being applied for. If you're applying for an Enterprise Architect position, then the following may be suitable:
First, you should create a proper Service-Oriented Architecture, as certainly the even-odd service won't be the only reusable component in your enterprise. An SOA consists of a service, interface, and service consumers. The service is function which can be invoked over the network. It exposes an interface contract and is typically registered with a Directory Service.
You can then create a Simple Object Access Protocol (SOAP) HTTP Web Service to expose your service.
Next, you should prevent clients from directly calling your Web Service. If you allow this, then you will end up with a mess of point-to-point communication, which is very hard to maintain. Clients should access the Web Service through an Enterprise Service Bus (ESB).
In addition to providing a standard plug-able architecture, additional components like service orchestration can occur on the bus.
Generally, writing a bespoke even/odd service should be avoided. You should write a Request for proposal (RFP), and get several vendors to show you their even/odd service. The vendor's product should be able to plug into your ESB, and also provide you with an Service level agreement (SLA).
In response to Chris Lutz, an array lookup is significantly slower than a BITWISE_AND operation. In an array lookup you're doing a memory lookup which will always be slower than a bitwise operation because of memory latency. This of course doesn't even factor in the problem of putting all possible int values into your array which has a memory complexity of O(2^n) where n is your bus size (8,16,32,64).
The odd/even property is only defined in integers. So any answer dealing with floating point is invalid. The abstract representation of this problem is Int -> bool (to use Haskell notation).