How can I check if a given number is even or odd in C?
我如何检查给定的数字是偶数还是奇数?
30 个解决方案
#1
446
Use the modulo (%) operator to check if there's a remainder when dividing by 2:
使用modulo(%)操作符检查是否在除以2时是否有余数:
if (x % 2) { /* x is odd */ }
A few people have criticized my answer above stating that using x & 1 is "faster" or "more efficient". I do not believe this to be the case.
一些人批评我的回答,上面说使用x和1是“更快”或“更有效率”。我不相信这是真的。
Out of curiosity, I created two trivial test case programs:
出于好奇,我创建了两个简单的测试用例程序:
/* modulo.c */
#include <stdio.h>
int main(void)
{
int x;
for (x = 0; x < 10; x++)
if (x % 2)
printf("%d is odd\n", x);
return 0;
}
/* and.c */
#include <stdio.h>
int main(void)
{
int x;
for (x = 0; x < 10; x++)
if (x & 1)
printf("%d is odd\n", x);
return 0;
}
I then compiled these with gcc 4.1.3 on one of my machines 5 different times:
然后我在我的一台机器上用gcc 4.1.3进行了编译:
- With no optimization flags.
- 没有优化的旗帜。
- With -O
- 与- o
- With -Os
- 与操作系统
- With -O2
- 与- 02
- With -O3
- 与o3
I examined the assembly output of each compile (using gcc -S) and found that in each case, the output for and.c and modulo.c were identical (they both used the andl $1, %eax instruction). I doubt this is a "new" feature, and I suspect it dates back to ancient versions. I also doubt any modern (made in the past 20 years) non-arcane compiler, commercial or open source, lacks such optimization. I would test on other compilers, but I don't have any available at the moment.
我检查了每个编译的汇编输出(使用gcc -S),并发现在每种情况下,输出都是为了和。c和模。c是相同的(他们都使用了andl $1, %eax指令)。我怀疑这是一个“新”特性,我怀疑它可以追溯到古代版本。我也怀疑任何现代(在过去的20年)非奥术编译器,商业或开源,缺乏这样的优化。我将对其他编译器进行测试,但目前没有可用的。
If anyone else would care to test other compilers and/or platform targets, and gets a different result, I'd be very interested to know.
如果其他人愿意测试其他编译器和/或平台目标,并得到一个不同的结果,我将非常有兴趣知道。
Finally, the modulo version is guaranteed by the standard to work whether the integer is positive, negative or zero, regardless of the implementation's representation of signed integers. The bitwise-and version is not. Yes, I realise two's complement is somewhat ubiquitous, so this is not really an issue.
最后,模块化版本得到了标准的保证,无论该整数是正的、负的还是零的,不管它的实现是如何表示有符号整数的。而bitwise和version则不是。是的,我意识到两种互补是无所不在的,所以这不是真正的问题。
#2
209
You guys are waaaaaaaay too efficient. What you really want is:
你们太有效率了。你真正想要的是:
public boolean isOdd(int num) {
int i = 0;
boolean odd = false;
while (i != num) {
odd = !odd;
i = i + 1;
}
return odd;
}
Repeat for isEven
.
重复做isEven。
Of course, that doesn't work for negative numbers. But with brilliance comes sacrifice...
当然,这并不适用于负数。但有了才华,就会有牺牲……
#3
97
Use bit arithmetic:
使用位运算:
if((x & 1) == 0)
printf("EVEN!\n");
else
printf("ODD!\n");
This is faster than using division or modulus.
这比使用除法或模量要快。
#4
36
[Joke mode="on"]
(笑话模式=“上”)
public enum Evenness
{
Unknown = 0,
Even = 1,
Odd = 2
}
public static Evenness AnalyzeEvenness(object o)
{
if (o == null)
return Evenness.Unknown;
string foo = o.ToString();
if (String.IsNullOrEmpty(foo))
return Evenness.Unknown;
char bar = foo[foo.Length - 1];
switch (bar)
{
case '0':
case '2':
case '4':
case '6':
case '8':
return Evenness.Even;
case '1':
case '3':
case '5':
case '7':
case '9':
return Evenness.Odd;
default:
return Evenness.Unknown;
}
}
[Joke mode="off"]
(笑话模式=“关闭”)
EDIT: Added confusing values to the enum.
编辑:将混淆的值添加到枚举。
#5
16
In response to ffpf - I had exactly the same argument with a colleague years ago, and the answer is no, it doesn't work with negative numbers.
作为对ffpf的回应,几年前我和一个同事有过同样的争论,答案是否定的,它与负数无关。
The C standard stipulates that negative numbers can be represented in 3 ways:
C标准规定负数可以用三种方式表示:
- 2's complement
- 2的补
- 1's complement
- 1的补
- sign and magnitude
- 签署和大小
Checking like this:
检查如下:
isEven = (x & 1);
will work for 2's complement and sign and magnitude representation, but not for 1's complement.
将为2的补码和符号和大小表示,而不是为1的补码。
However, I believe that the following will work for all cases:
但是,我认为以下的方法适用于所有情况:
isEven = (x & 1) ^ ((-1 & 1) | ((x < 0) ? 0 : 1)));
Thanks to ffpf for pointing out that the text box was eating everything after my less than character!
感谢ffpf指出,文本框在我的文字之后就开始吃东西了!
#6
14
A nice one is:
一个漂亮的一个是:
/*forward declaration, C compiles in one pass*/
bool isOdd(unsigned int n);
bool isEven(unsigned int n)
{
if (n == 0)
return true ; // I know 0 is even
else
return isOdd(n-1) ; // n is even if n-1 is odd
}
bool isOdd(unsigned int n)
{
if (n == 0)
return false ;
else
return isEven(n-1) ; // n is odd if n-1 is even
}
Note that this method use tail recursion involving two functions. It can be implemented efficiently (turned into a while/until kind of loop) if your compiler supports tail recursion like a Scheme compiler. In this case the stack should not overflow !
注意,该方法使用了包含两个函数的尾部递归。如果编译器像Scheme编译器一样支持尾递归,则可以有效地实现它(转换为一段时间/直到某种循环)。在这种情况下,堆栈不应该溢出!
#7
11
A number is even if, when divided by two, the remainder is 0. A number is odd if, when divided by 2, the remainder is 1.
一个数是偶数,当除以2时,余数为0。一个数是奇数,如果除以2,余数是1。
// Java
public static boolean isOdd(int num){
return num % 2 != 0;
}
/* C */
int isOdd(int num){
return num % 2;
}
Methods are great!
方法太棒了!
#8
8
i % 2 == 0
#9
7
I'd say just divide it by 2 and if there is a 0 remainder, it's even, otherwise it's odd.
我把它除以2,如果余数是0,它是偶数,否则它是奇数。
Using the modulus (%) makes this easy.
使用模量(%)使这个简单。
eg. 4 % 2 = 0 therefore 4 is even 5 % 2 = 1 therefore 5 is odd
如。4 % 2 = 0,因此4 = 5 % 2 = 1因此5是奇数。
#10
6
One more solution to the problem
(children are welcome to vote)
还有一个解决这个问题的办法(欢迎孩子们投票)
bool isEven(unsigned int x)
{
unsigned int half1 = 0, half2 = 0;
while (x)
{
if (x) { half1++; x--; }
if (x) { half2++; x--; }
}
return half1 == half2;
}
#11
6
I would build a table of the parities (0 if even 1 if odd) of the integers (so one could do a lookup :D), but gcc won't let me make arrays of such sizes:
我将构建一个整数表(如果奇数的话为0)(因此可以进行查找:D),但是gcc不让我做这样大小的数组:
typedef unsigned int uint;
char parity_uint [UINT_MAX];
char parity_sint_shifted [((uint) INT_MAX) + ((uint) abs (INT_MIN))];
char* parity_sint = parity_sint_shifted - INT_MIN;
void build_parity_tables () {
char parity = 0;
unsigned int ui;
for (ui = 1; ui <= UINT_MAX; ++ui) {
parity_uint [ui - 1] = parity;
parity = !parity;
}
parity = 0;
int si;
for (si = 1; si <= INT_MAX; ++si) {
parity_sint [si - 1] = parity;
parity = !parity;
}
parity = 1;
for (si = -1; si >= INT_MIN; --si) {
parity_sint [si] = parity;
parity = !parity;
}
}
char uparity (unsigned int n) {
if (n == 0) {
return 0;
}
return parity_uint [n - 1];
}
char sparity (int n) {
if (n == 0) {
return 0;
}
if (n < 0) {
++n;
}
return parity_sint [n - 1];
}
So let's instead resort to the mathematical definition of even and odd instead.
因此,让我们转而求助于偶数和奇数的数学定义。
An integer n is even if there exists an integer k such that n = 2k.
整数n,即使存在整数k,也就是n = 2k。
An integer n is odd if there exists an integer k such that n = 2k + 1.
整数n是奇数,如果存在整数k,那么n = 2k + 1。
Here's the code for it:
下面是它的代码:
char even (int n) {
int k;
for (k = INT_MIN; k <= INT_MAX; ++k) {
if (n == 2 * k) {
return 1;
}
}
return 0;
}
char odd (int n) {
int k;
for (k = INT_MIN; k <= INT_MAX; ++k) {
if (n == 2 * k + 1) {
return 1;
}
}
return 0;
}
Let C-integers denote the possible values of int
in a given C compilation. (Note that C-integers is a subset of the integers.)
在给定的C编译中,让C-integer表示int的可能值。(注意,c -integer是整数的一个子集。)
Now one might worry that for a given n in C-integers that the corresponding integer k might not exist within C-integers. But with a little proof it is can be shown that for all integers n, |n| <= |2n| (*), where |n| is "n if n is positive and -n otherwise". In other words, for all n in integers at least one of the following holds (exactly either cases (1 and 2) or cases (3 and 4) in fact but I won't prove it here):
现在有人可能会担心,对于给定的n,在c整数中,对应的整数k可能不存在于c整数中。但是,有一点证明可以证明,对于所有整数n, |n| <= |2n|(*),其中|n|是“n如果n是正的,否则是-n”。换句话说,对于所有n的整数,至少有一种情况是这样的(1和2)或者情况(3和4),但我不会在这里证明它):
Case 1: n <= 2n.
案例1:n <= 2n。
Case 2: -n <= -2n.
情形2:-n <= -2n。
Case 3: -n <= 2n.
案例3:-n <= 2n。
Case 4: n <= -2n.
案例4:n <= -2n。
Now take 2k = n. (Such a k does exist if n is even, but I won't prove it here. If n is not even then the loop in even
fails to return early anyway, so it doesn't matter.) But this implies k < n if n not 0 by (*) and the fact (again not proven here) that for all m, z in integers 2m = z implies z not equal to m given m is not 0. In the case n is 0, 2*0 = 0 so 0 is even we are done (if n = 0 then 0 is in C-integers because n is in C-integer in the function even
, hence k = 0 is in C-integers). Thus such a k in C-integers exists for n in C-integers if n is even.
现在取2k = n(如果n是偶数,那么k是存在的,但这里我不证明它。如果n不是偶数,那么循环甚至不能提前返回,所以没关系。但这意味着k < n如果n不是0(*)和这个事实(这里还没有证明)对于所有m, z的整数2m = z意味着z不等于m,因为m不是0。在这个例子中,n = 0, 2*0 = 0,所以0是偶数,如果n = 0,那么0是c整数,因为n在函数中是c整数,因此k = 0是c -整数。因此,如果n是偶数,那么c -整数中的k是存在的。
A similar argument shows that if n is odd, there exists a k in C-integers such that n = 2k + 1.
一个类似的论证表明,如果n是奇数,那么在c整数中存在一个k,这样n = 2k + 1。
Hence the functions even
and odd
presented here will work properly for all C-integers.
因此,这里给出的函数甚至是奇数,都适用于所有的c整数。
#12
5
// C#
bool isEven = ((i % 2) == 0);
#13
5
This is a follow up to the discussion with @RocketRoy regarding his answer, but it might be useful to anyone who wants to compare these results.
这是关于他的回答与@RocketRoy讨论的后续,但是对于任何想要比较这些结果的人来说,这可能是有用的。
tl;dr From what I've seen, Roy's approach ((0xFFFFFFFF == (x | 0xFFFFFFFE)
) is not completely optimized to x & 1
as the mod
approach, but in practice running times should turn out equal in all cases.
从我所看到的来看,Roy的方法((0xFFFFFFFF == (x | 0xFFFFFFFE))并没有完全优化到x & 1作为mod方法,但是在实际运行中,在所有情况下都应该是相同的。
So, first I compared the compiled output using Compiler Explorer:
所以,首先我使用编译器浏览器比较编译后的输出:
Functions tested:
功能测试:
int isOdd_mod(unsigned x) {
return (x % 2);
}
int isOdd_and(unsigned x) {
return (x & 1);
}
int isOdd_or(unsigned x) {
return (0xFFFFFFFF == (x | 0xFFFFFFFE));
}
CLang 3.9.0 with -O3:
铿锵声3.9.0 o3:
isOdd_mod(unsigned int): # @isOdd_mod(unsigned int)
and edi, 1
mov eax, edi
ret
isOdd_and(unsigned int): # @isOdd_and(unsigned int)
and edi, 1
mov eax, edi
ret
isOdd_or(unsigned int): # @isOdd_or(unsigned int)
and edi, 1
mov eax, edi
ret
GCC 6.2 with -O3:
GCC 6.2 o3:
isOdd_mod(unsigned int):
mov eax, edi
and eax, 1
ret
isOdd_and(unsigned int):
mov eax, edi
and eax, 1
ret
isOdd_or(unsigned int):
or edi, -2
xor eax, eax
cmp edi, -1
sete al
ret
Hats down to CLang, it realized that all three cases are functionally equal. However, Roy's approach isn't optimized in GCC, so YMMV.
向CLang致敬,它意识到这三个案例在功能上是平等的。然而,在GCC中,Roy的方法并没有得到优化,所以YMMV。
It's similar with Visual Studio; inspecting the disassembly Release x64 (VS2015) for these three functions, I could see that the comparison part is equal for "mod" and "and" cases, and slightly larger for the Roy's "or" case:
它与Visual Studio相似;检查disassembly Release x64 (VS2015)对于这三个函数,我可以看到比较部分等于“mod”和“and”的情况,对于Roy的“or”案例稍微大一点:
// x % 2
test bl,1
je (some address)
// x & 1
test bl,1
je (some address)
// Roy's bitwise or
mov eax,ebx
or eax,0FFFFFFFEh
cmp eax,0FFFFFFFFh
jne (some address)
However, after running an actual benchmark for comparing these three options (plain mod, bitwise or, bitwise and), results were completely equal (again, Visual Studio 2005 x86/x64, Release build, no debugger attached).
然而,在运行一个实际的基准来比较这三个选项(plain mod、bitwise或bitwise和)之后,结果是完全相同的(同样,Visual Studio 2005 x86/x64,发布版本,没有附加调试器)。
Release assembly uses the test
instruction for and
and mod
cases, while Roy's case uses the cmp eax,0FFFFFFFFh
approach, but it's heavily unrolled and optimized so there is no difference in practice.
发布程序集使用测试指令和mod案例,而Roy的案例使用cmp eax,0FFFFFFFFh方法,但是它是大量展开和优化的,所以在实践中没有区别。
My results after 20 runs (i7 3610QM, Windows 10 power plan set to High Performance):
我在20次运行后的结果(i7 3610QM, Windows 10 power plan设置为高性能):
[Test: Plain mod 2 ] AVERAGE TIME: 689.29 ms (Relative diff.: +0.000%) [Test: Bitwise or ] AVERAGE TIME: 689.63 ms (Relative diff.: +0.048%) [Test: Bitwise and ] AVERAGE TIME: 687.80 ms (Relative diff.: -0.217%)
The difference between these options is less than 0.3%, so it's rather obvious the assembly is equal in all cases.
这些选项之间的差异小于0.3%,所以很明显,在所有情况下程序集都是相等的。
Here is the code if anyone wants to try, with a caveat that I only tested it on Windows (check the #if LINUX
conditional for the get_time
definition and implement it if needed, taken from this answer).
这里是代码,如果有人想尝试,我只在Windows上测试过它(如果需要的话,请检查#if LINUX条件是否为get_time定义并在需要时实现它)。
#include <stdio.h>
#if LINUX
#include <sys/time.h>
#include <sys/resource.h>
double get_time()
{
struct timeval t;
struct timezone tzp;
gettimeofday(&t, &tzp);
return t.tv_sec + t.tv_usec*1e-6;
}
#else
#include <windows.h>
double get_time()
{
LARGE_INTEGER t, f;
QueryPerformanceCounter(&t);
QueryPerformanceFrequency(&f);
return (double)t.QuadPart / (double)f.QuadPart * 1000.0;
}
#endif
#define NUM_ITERATIONS (1000 * 1000 * 1000)
// using a macro to avoid function call overhead
#define Benchmark(accumulator, name, operation) { \
double startTime = get_time(); \
double dummySum = 0.0, elapsed; \
int x; \
for (x = 0; x < NUM_ITERATIONS; x++) { \
if (operation) dummySum += x; \
} \
elapsed = get_time() - startTime; \
accumulator += elapsed; \
if (dummySum > 2000) \
printf("[Test: %-12s] %0.2f ms\r\n", name, elapsed); \
}
void DumpAverage(char *test, double totalTime, double reference)
{
printf("[Test: %-12s] AVERAGE TIME: %0.2f ms (Relative diff.: %+6.3f%%)\r\n",
test, totalTime, (totalTime - reference) / reference * 100.0);
}
int main(void)
{
int repeats = 20;
double runningTimes[3] = { 0 };
int k;
for (k = 0; k < repeats; k++) {
printf("Run %d of %d...\r\n", k + 1, repeats);
Benchmark(runningTimes[0], "Plain mod 2", (x % 2));
Benchmark(runningTimes[1], "Bitwise or", (0xFFFFFFFF == (x | 0xFFFFFFFE)));
Benchmark(runningTimes[2], "Bitwise and", (x & 1));
}
{
double reference = runningTimes[0] / repeats;
printf("\r\n");
DumpAverage("Plain mod 2", runningTimes[0] / repeats, reference);
DumpAverage("Bitwise or", runningTimes[1] / repeats, reference);
DumpAverage("Bitwise and", runningTimes[2] / repeats, reference);
}
getchar();
return 0;
}
#14
4
Here is an answer in Java:
下面是Java的一个答案:
public static boolean isEven (Integer Number) {
Pattern number = Pattern.compile("^.*?(?:[02]|8|(?:6|4))$");
String num = Number.toString(Number);
Boolean numbr = new Boolean(number.matcher(num).matches());
return numbr.booleanValue();
}
#15
4
As some people have posted, there are numerous ways to do this. According to this website, the fastest way is the modulus operator:
正如一些人发布的,有很多方法可以做到这一点。根据这个网站,最快的方法是模量算符:
if (x % 2 == 0)
total += 1; //even number
else
total -= 1; //odd number
However, here is some other code that was bench marked by the author which ran slower than the common modulus operation above:
但是,这里还有一些其他的代码,是由作者标记的,其运行速度比上面的普通模量操作要慢:
if ((x & 1) == 0)
total += 1; //even number
else
total -= 1; //odd number
System.Math.DivRem((long)x, (long)2, out outvalue);
if ( outvalue == 0)
total += 1; //even number
else
total -= 1; //odd number
if (((x / 2) * 2) == x)
total += 1; //even number
else
total -= 1; //odd number
if (((x >> 1) << 1) == x)
total += 1; //even number
else
total -= 1; //odd number
while (index > 1)
index -= 2;
if (index == 0)
total += 1; //even number
else
total -= 1; //odd number
tempstr = x.ToString();
index = tempstr.Length - 1;
//this assumes base 10
if (tempstr[index] == '0' || tempstr[index] == '2' || tempstr[index] == '4' || tempstr[index] == '6' || tempstr[index] == '8')
total += 1; //even number
else
total -= 1; //odd number
How many people even knew of the Math.System.DivRem method or why would they use it??
有多少人知道这个数学系统。他们为什么要用这个方法?
#16
4
Try this: return (((a>>1)<<1) == a)
试试这个:return((一个>>1)<<1)== a)
Example:
例子:
a = 10101011
-----------------
a>>1 --> 01010101
a<<1 --> 10101010
b = 10011100
-----------------
b>>1 --> 01001110
b<<1 --> 10011100
#17
4
Reading this rather entertaining discussion, I remembered that I had a real-world, time-sensitive function that tested for odd and even numbers inside the main loop. It's an integer power function, posted elsewhere on *, as follows. The benchmarks were quite surprising. At least in this real-world function, modulo is slower, and significantly so. The winner, by a wide margin, requiring 67% of modulo's time, is an or ( | ) approach, and is nowhere to be found elsewhere on this page.
阅读这篇有趣的讨论,我记得我有一个真实的、时间敏感的函数,它在主循环中测试奇数和偶数。它是一个整数幂函数,发布在*的其他地方,如下所示。基准测试非常令人吃惊。至少在这个现实世界的函数中,模块化是比较慢的,而且是显著的。胜出者,以很大的差距,需要67%的模组时间,是一个或(|)方法,并且在这一页的其他地方找不到。
static dbl IntPow(dbl st0, int x) {
UINT OrMask = UINT_MAX -1;
dbl st1=1.0;
if(0==x) return (dbl)1.0;
while(1 != x) {
if (UINT_MAX == (x|OrMask)) { // if LSB is 1...
//if(x & 1) {
//if(x % 2) {
st1 *= st0;
}
x = x >> 1; // shift x right 1 bit...
st0 *= st0;
}
return st1 * st0;
}
For 300 million loops, the benchmark timings are as follows.
对于3亿个循环,基准计时如下。
3.962 the | and mask approach
3.962 |和掩模方法。
4.851 the & approach
4.851 &方法
5.850 the % approach
5.850 %的方法
For people who think theory, or an assembly language listing, settles arguments like these, this should be a cautionary tale. There are more things in heaven and earth, Horatio, than are dreamt of in your philosophy.
对于那些认为理论或汇编语言清单的人来说,这应该是一个警示的故事。天地间有更多的东西,荷瑞修,比你的哲学所梦想的还要多。
#18
3
I know this is just syntactic sugar and only applicable in .net but what about extension method...
我知道这只是语法糖,只适用于。net,但是扩展方法……
public static class RudiGroblerExtensions
{
public static bool IsOdd(this int i)
{
return ((i % 2) != 0);
}
}
Now you can do the following
现在您可以执行以下操作。
int i = 5;
if (i.IsOdd())
{
// Do something...
}
#19
3
In the "creative but confusing category" I offer:
在“创造性但令人困惑的类别”中,我提供:
int isOdd(int n) { return n ^ n * n ? isOdd(n * n) : n; }
A variant on this theme that is specific to Microsoft C++:
这个主题的一个变体是针对微软c++的:
__declspec(naked) bool __fastcall isOdd(const int x)
{
__asm
{
mov eax,ecx
mul eax
mul eax
mul eax
mul eax
mul eax
mul eax
ret
}
}
#20
2
The bitwise method depends on the inner representation of the integer. Modulo will work anywhere there is a modulo operator. For example, some systems actually use the low level bits for tagging (like dynamic languages), so the raw x & 1 won't actually work in that case.
位方法依赖于整数的内部表示。Modulo在任何地方都可以工作。例如,有些系统实际上使用低级别的标记(比如动态语言),因此原始的x & 1在这种情况下不会实际工作。
#21
2
IsOdd(int x) { return true; }
IsOdd(int x){返回true;}
Proof of correctness - consider the set of all positive integers and suppose there is a non-empty set of integers that are not odd. Because positive integers are well-ordered, there will be a smallest not odd number, which in itself is pretty odd, so clearly that number can't be in the set. Therefore this set cannot be non-empty. Repeat for negative integers except look for the greatest not odd number.
正确性的证明——考虑所有正整数的集合,假设有一个非空的整数集,它们并不奇怪。因为正整数是有序的,所以会有一个最小的不是奇数,这本身是很奇怪的,所以很明显这个数不能在集合中,所以这个集合不能是非空的。对负整数重复,除了寻找最大的不是奇数。
#22
2
Portable:
便携式:
i % 2 ? odd : even;
Unportable:
Unportable:
i & 1 ? odd : even;
i << (BITS_PER_INT - 1) ? odd : even;
#23
1
int isOdd(int i){
return(i % 2);
}
done.
完成了。
#24
1
To give more elaboration on the bitwise operator method for those of us who didn't do much boolean algebra during our studies, here is an explanation. Probably not of much use to the OP, but I felt like making it clear why NUMBER & 1 works.
为了更详细地说明我们在学习过程中没有做大量布尔代数的人,这里有一个解释。可能对OP没有多大用处,但我想清楚为什么数字和1可以工作。
Please note like as someone answered above, the way negative numbers are represented can stop this method working. In fact it can even break the modulo operator method too since each language can differ in how it deals with negative operands.
请注意,就像有人在上面回答的那样,负数的表示方式可以阻止这个方法的工作。事实上,它甚至可以打破模运算符的方法,因为每种语言在处理负操作数时都有不同。
However if you know that NUMBER will always be positive, this works well.
然而,如果你知道这个数字永远是正数,这就很有效。
As Tooony above made the point that only the last digit in binary (and denary) is important.
正如图奥尼所指出的那样,只有二进制(和denary)中的最后一个数字是重要的。
A boolean logic AND gate dictates that both inputs have to be a 1 (or high voltage) for 1 to be returned.
布尔逻辑和gate规定,两个输入必须是1(或高电压)才能返回。
1 & 0 = 0.
1 & 0 = 0。
0 & 1 = 0.
0和1 = 0。
0 & 0 = 0.
0和0 = 0。
1 & 1 = 1.
1 & 1 = 1。
If you represent any number as binary (I have used an 8 bit representation here), odd numbers have 1 at the end, even numbers have 0.
如果你把任意数字表示为二进制(我在这里用了8位表示),奇数的末尾有1,偶数是0。
For example:
例如:
1 = 00000001
1 = 00000001
2 = 00000010
2 = 00000010
3 = 00000011
3 = 00000011
4 = 00000100
4 = 00000100
If you take any number and use bitwise AND (& in java) it by 1 it will either return 00000001, = 1 meaning the number is odd. Or 00000000 = 0, meaning the number is even.
如果你取任意一个数字并使用bitwise和(& in java),它将返回00000001,= 1表示这个数字是奇数。或者00000000 = 0,也就是说这个数是偶数。
E.g
如
Is odd?
很奇怪吗?
1 & 1 =
1 & 1 =
00000001 &
00000001 &
00000001 =
00000001 =
00000001 <— Odd
00000001 <余< p>
2 & 1 =
2和1 =
00000010 &
00000010 &
00000001 =
00000001 =
00000000 <— Even
00000000 <——甚至
54 & 1 =
54 & 1 =
00000001 &
00000001 &
00110110 =
00110110 =
00000000 <— Even
00000000 <——甚至
This is why this works:
这就是为什么这样做的原因:
if(number & 1){
//Number is odd
} else {
//Number is even
}
Sorry if this is redundant.
抱歉,这是多余的。
#25
1
Number Zero parity | zero http://tinyurl.com/oexhr3k
数字0对等| 0 http://tinyurl.com/oexhr3k。
Python code sequence.
Python代码序列。
# defining function for number parity check
def parity(number):
"""Parity check function"""
# if number is 0 (zero) return 'Zero neither ODD nor EVEN',
# otherwise number&1, checking last bit, if 0, then EVEN,
# if 1, then ODD.
return (number == 0 and 'Zero neither ODD nor EVEN') \
or (number&1 and 'ODD' or 'EVEN')
# cycle trough numbers from 0 to 13
for number in range(0, 14):
print "{0:>4} : {0:08b} : {1:}".format(number, parity(number))
Output:
输出:
0 : 00000000 : Zero neither ODD nor EVEN
1 : 00000001 : ODD
2 : 00000010 : EVEN
3 : 00000011 : ODD
4 : 00000100 : EVEN
5 : 00000101 : ODD
6 : 00000110 : EVEN
7 : 00000111 : ODD
8 : 00001000 : EVEN
9 : 00001001 : ODD
10 : 00001010 : EVEN
11 : 00001011 : ODD
12 : 00001100 : EVEN
13 : 00001101 : ODD
#26
1
I execute this code for ODD & EVEN:
#include <stdio.h>
int main()
{
int number;
printf("Enter an integer: ");
scanf("%d", &number);
if(number % 2 == 0)
printf("%d is even.", number);
else
printf("%d is odd.", number);
}
#27
0
For the sake of discussion...
为了讨论……
You only need to look at the last digit in any given number to see if it is even or odd. Signed, unsigned, positive, negative - they are all the same with regards to this. So this should work all round: -
你只需要看一个给定数字的最后一个数字,看看它是偶数还是奇数。签名,无符号,正面,负面-这些都是一样的。因此,这应该是一个全面的工作:-。
void tellMeIfItIsAnOddNumberPlease(int iToTest){
int iLastDigit;
iLastDigit = iToTest - (iToTest / 10 * 10);
if (iLastDigit % 2 == 0){
printf("The number %d is even!\n", iToTest);
} else {
printf("The number %d is odd!\n", iToTest);
}
}
The key here is in the third line of code, the division operator performs an integer division, so that result are missing the fraction part of the result. So for example 222 / 10 will give 22 as a result. Then multiply it again with 10 and you have 220. Subtract that from the original 222 and you end up with 2, which by magic is the same number as the last digit in the original number. ;-) The parenthesis are there to remind us of the order the calculation is done in. First do the division and the multiplication, then subtract the result from the original number. We could leave them out, since the priority is higher for division and multiplication than of subtraction, but this gives us "more readable" code.
这里的关键是在第三行代码中,除法运算符执行一个整数除法,所以结果会忽略掉分数部分。比如222 / 10,结果是22。再乘以10,得到220。从原来的222减去它,最后得到2,它和原来的数字是一样的。括号是用来提醒我们计算所做的顺序的。首先做除法和乘法运算,然后减去原数的结果。我们可以省略它们,因为优先级比减法要高,但这给了我们“更可读”的代码。
We could make it all completely unreadable if we wanted to. It would make no difference whatsoever for a modern compiler: -
如果我们想的话,我们可以让它完全无法读懂。对于一个现代的编译器来说,它是没有任何区别的:-。
printf("%d%s\n",iToTest,0==(iToTest-iToTest/10*10)%2?" is even":" is odd");
But it would make the code way harder to maintain in the future. Just imagine that you would like to change the text for odd numbers to "is not even". Then someone else later on want to find out what changes you made and perform a svn diff or similar...
但这将使代码在将来更难维护。想象一下,你想要把奇数变成“甚至不是”。然后其他人想知道你做了什么改变并执行了svn diff或类似的…
If you are not worried about portability but more about speed, you could have a look at the least significant bit. If that bit is set to 1 it is an odd number, if it is 0 it's an even number. On a little endian system, like Intel's x86 architecture it would be something like this: -
如果您不担心可移植性,但更关心的是速度,那么您可以看一下最不重要的部分。如果这个位被设为1这是个奇数,如果是0,它就是偶数。在一个小的endian系统上,就像Intel的x86架构一样,它会是这样的:-。
if (iToTest & 1) {
// Even
} else {
// Odd
}
#28
0
If you want to be efficient, use bitwise operators (x & 1
), but if you want to be readable use modulo 2 (x % 2
)
如果您想要高效,请使用位操作符(x & 1),但是如果您想要具有可读的使用模块2 (x % 2)
#29
0
Checking even or odd is a simple task.
检查偶数或奇数是一项简单的任务。
We know that any number exactly divisible by 2 is even number else odd.
我们知道任何能被2整除的数都是奇数。
We just need to check divisibility of any number and for checking divisibility we use %
operator
我们只需要检查任何数字的可分割性,并检查可分度,我们使用%运算符。
Checking even odd using if else
检查偶数,用if else。
if(num%2 ==0)
{
printf("Even");
}
else
{
printf("Odd");
}
C program to check even or odd using if else
C程序检查偶数或奇数使用。
Using Conditional/Ternary operator
使用条件/三元操作符
(num%2 ==0) printf("Even") : printf("Odd");
C program to check even or odd using conditional operator.
C程序使用条件运算符检查偶数或奇数。
Using Bitwise operator
使用位操作符
if(num & 1)
{
printf("Odd");
}
else
{
printf("Even");
}
#30
-1
Modulus operator '%' can be used to check whether a number is odd or even.That is when a number is divided by 2 and if the remainder is 0 then its an even number else its an odd number.
模数运算符'%'可以用来检验一个数字是奇数还是偶数。也就是说,当一个数除以2,如果余数是0,那么它的偶数就是一个奇数。
#include <stdio.h>
int main()
{
int n;//using modulus operator
scanf("%d",&n);//take input n from STDIN
printf("%s",n%2==0?"Even":"Odd");//prints Even/Odd depending on n to STDOUT
return 0;
}
But using Bit manipulation is quite faster than the above method,so if you take a number and apply logically AND '&' to it ,if the answer is 1 then its even else its odd.That is basically we have to check the last bit of the number n in binary.If the last bit is 0 then n is even else its odd.
但是使用位操作的速度要比上面的方法快得多,所以如果你取一个数字,并在逻辑上和“&”上应用,如果答案是1,那么它的奇数也会是偶数。这就是我们要检查n在二进制中的最后一点。如果最后一点是0,那么n就是奇数。
for example : suppose N = 15 , in binary N = 1111 , now we AND it with 1
例如:假设N = 15,在二进制N = 1111中,现在我们和它是1。
1111
0001
&-----
0001
Since the result is 1 the number N=15 is Odd.
Again,suppose N = 8 , in binary N = 1000 , now we AND it with 1
因为结果是1 N=15是奇数。再一次,假设N = 8,在二进制N = 1000,现在是1。
1000
0001
&-----
0000
Since the result is 0 the number N=8 is Even.
因为结果是0,所以N=8是偶数。
#include <stdio.h>
int main()
{
int n;//using AND operator
scanf("%d",&n);//take input n from STDIN
printf("%s",n&1?"Odd":"Even");//prints Even/Odd depending on n to STDOUT
return 0;
}
#1
446
Use the modulo (%) operator to check if there's a remainder when dividing by 2:
使用modulo(%)操作符检查是否在除以2时是否有余数:
if (x % 2) { /* x is odd */ }
A few people have criticized my answer above stating that using x & 1 is "faster" or "more efficient". I do not believe this to be the case.
一些人批评我的回答,上面说使用x和1是“更快”或“更有效率”。我不相信这是真的。
Out of curiosity, I created two trivial test case programs:
出于好奇,我创建了两个简单的测试用例程序:
/* modulo.c */
#include <stdio.h>
int main(void)
{
int x;
for (x = 0; x < 10; x++)
if (x % 2)
printf("%d is odd\n", x);
return 0;
}
/* and.c */
#include <stdio.h>
int main(void)
{
int x;
for (x = 0; x < 10; x++)
if (x & 1)
printf("%d is odd\n", x);
return 0;
}
I then compiled these with gcc 4.1.3 on one of my machines 5 different times:
然后我在我的一台机器上用gcc 4.1.3进行了编译:
- With no optimization flags.
- 没有优化的旗帜。
- With -O
- 与- o
- With -Os
- 与操作系统
- With -O2
- 与- 02
- With -O3
- 与o3
I examined the assembly output of each compile (using gcc -S) and found that in each case, the output for and.c and modulo.c were identical (they both used the andl $1, %eax instruction). I doubt this is a "new" feature, and I suspect it dates back to ancient versions. I also doubt any modern (made in the past 20 years) non-arcane compiler, commercial or open source, lacks such optimization. I would test on other compilers, but I don't have any available at the moment.
我检查了每个编译的汇编输出(使用gcc -S),并发现在每种情况下,输出都是为了和。c和模。c是相同的(他们都使用了andl $1, %eax指令)。我怀疑这是一个“新”特性,我怀疑它可以追溯到古代版本。我也怀疑任何现代(在过去的20年)非奥术编译器,商业或开源,缺乏这样的优化。我将对其他编译器进行测试,但目前没有可用的。
If anyone else would care to test other compilers and/or platform targets, and gets a different result, I'd be very interested to know.
如果其他人愿意测试其他编译器和/或平台目标,并得到一个不同的结果,我将非常有兴趣知道。
Finally, the modulo version is guaranteed by the standard to work whether the integer is positive, negative or zero, regardless of the implementation's representation of signed integers. The bitwise-and version is not. Yes, I realise two's complement is somewhat ubiquitous, so this is not really an issue.
最后,模块化版本得到了标准的保证,无论该整数是正的、负的还是零的,不管它的实现是如何表示有符号整数的。而bitwise和version则不是。是的,我意识到两种互补是无所不在的,所以这不是真正的问题。
#2
209
You guys are waaaaaaaay too efficient. What you really want is:
你们太有效率了。你真正想要的是:
public boolean isOdd(int num) {
int i = 0;
boolean odd = false;
while (i != num) {
odd = !odd;
i = i + 1;
}
return odd;
}
Repeat for isEven
.
重复做isEven。
Of course, that doesn't work for negative numbers. But with brilliance comes sacrifice...
当然,这并不适用于负数。但有了才华,就会有牺牲……
#3
97
Use bit arithmetic:
使用位运算:
if((x & 1) == 0)
printf("EVEN!\n");
else
printf("ODD!\n");
This is faster than using division or modulus.
这比使用除法或模量要快。
#4
36
[Joke mode="on"]
(笑话模式=“上”)
public enum Evenness
{
Unknown = 0,
Even = 1,
Odd = 2
}
public static Evenness AnalyzeEvenness(object o)
{
if (o == null)
return Evenness.Unknown;
string foo = o.ToString();
if (String.IsNullOrEmpty(foo))
return Evenness.Unknown;
char bar = foo[foo.Length - 1];
switch (bar)
{
case '0':
case '2':
case '4':
case '6':
case '8':
return Evenness.Even;
case '1':
case '3':
case '5':
case '7':
case '9':
return Evenness.Odd;
default:
return Evenness.Unknown;
}
}
[Joke mode="off"]
(笑话模式=“关闭”)
EDIT: Added confusing values to the enum.
编辑:将混淆的值添加到枚举。
#5
16
In response to ffpf - I had exactly the same argument with a colleague years ago, and the answer is no, it doesn't work with negative numbers.
作为对ffpf的回应,几年前我和一个同事有过同样的争论,答案是否定的,它与负数无关。
The C standard stipulates that negative numbers can be represented in 3 ways:
C标准规定负数可以用三种方式表示:
- 2's complement
- 2的补
- 1's complement
- 1的补
- sign and magnitude
- 签署和大小
Checking like this:
检查如下:
isEven = (x & 1);
will work for 2's complement and sign and magnitude representation, but not for 1's complement.
将为2的补码和符号和大小表示,而不是为1的补码。
However, I believe that the following will work for all cases:
但是,我认为以下的方法适用于所有情况:
isEven = (x & 1) ^ ((-1 & 1) | ((x < 0) ? 0 : 1)));
Thanks to ffpf for pointing out that the text box was eating everything after my less than character!
感谢ffpf指出,文本框在我的文字之后就开始吃东西了!
#6
14
A nice one is:
一个漂亮的一个是:
/*forward declaration, C compiles in one pass*/
bool isOdd(unsigned int n);
bool isEven(unsigned int n)
{
if (n == 0)
return true ; // I know 0 is even
else
return isOdd(n-1) ; // n is even if n-1 is odd
}
bool isOdd(unsigned int n)
{
if (n == 0)
return false ;
else
return isEven(n-1) ; // n is odd if n-1 is even
}
Note that this method use tail recursion involving two functions. It can be implemented efficiently (turned into a while/until kind of loop) if your compiler supports tail recursion like a Scheme compiler. In this case the stack should not overflow !
注意,该方法使用了包含两个函数的尾部递归。如果编译器像Scheme编译器一样支持尾递归,则可以有效地实现它(转换为一段时间/直到某种循环)。在这种情况下,堆栈不应该溢出!
#7
11
A number is even if, when divided by two, the remainder is 0. A number is odd if, when divided by 2, the remainder is 1.
一个数是偶数,当除以2时,余数为0。一个数是奇数,如果除以2,余数是1。
// Java
public static boolean isOdd(int num){
return num % 2 != 0;
}
/* C */
int isOdd(int num){
return num % 2;
}
Methods are great!
方法太棒了!
#8
8
i % 2 == 0
#9
7
I'd say just divide it by 2 and if there is a 0 remainder, it's even, otherwise it's odd.
我把它除以2,如果余数是0,它是偶数,否则它是奇数。
Using the modulus (%) makes this easy.
使用模量(%)使这个简单。
eg. 4 % 2 = 0 therefore 4 is even 5 % 2 = 1 therefore 5 is odd
如。4 % 2 = 0,因此4 = 5 % 2 = 1因此5是奇数。
#10
6
One more solution to the problem
(children are welcome to vote)
还有一个解决这个问题的办法(欢迎孩子们投票)
bool isEven(unsigned int x)
{
unsigned int half1 = 0, half2 = 0;
while (x)
{
if (x) { half1++; x--; }
if (x) { half2++; x--; }
}
return half1 == half2;
}
#11
6
I would build a table of the parities (0 if even 1 if odd) of the integers (so one could do a lookup :D), but gcc won't let me make arrays of such sizes:
我将构建一个整数表(如果奇数的话为0)(因此可以进行查找:D),但是gcc不让我做这样大小的数组:
typedef unsigned int uint;
char parity_uint [UINT_MAX];
char parity_sint_shifted [((uint) INT_MAX) + ((uint) abs (INT_MIN))];
char* parity_sint = parity_sint_shifted - INT_MIN;
void build_parity_tables () {
char parity = 0;
unsigned int ui;
for (ui = 1; ui <= UINT_MAX; ++ui) {
parity_uint [ui - 1] = parity;
parity = !parity;
}
parity = 0;
int si;
for (si = 1; si <= INT_MAX; ++si) {
parity_sint [si - 1] = parity;
parity = !parity;
}
parity = 1;
for (si = -1; si >= INT_MIN; --si) {
parity_sint [si] = parity;
parity = !parity;
}
}
char uparity (unsigned int n) {
if (n == 0) {
return 0;
}
return parity_uint [n - 1];
}
char sparity (int n) {
if (n == 0) {
return 0;
}
if (n < 0) {
++n;
}
return parity_sint [n - 1];
}
So let's instead resort to the mathematical definition of even and odd instead.
因此,让我们转而求助于偶数和奇数的数学定义。
An integer n is even if there exists an integer k such that n = 2k.
整数n,即使存在整数k,也就是n = 2k。
An integer n is odd if there exists an integer k such that n = 2k + 1.
整数n是奇数,如果存在整数k,那么n = 2k + 1。
Here's the code for it:
下面是它的代码:
char even (int n) {
int k;
for (k = INT_MIN; k <= INT_MAX; ++k) {
if (n == 2 * k) {
return 1;
}
}
return 0;
}
char odd (int n) {
int k;
for (k = INT_MIN; k <= INT_MAX; ++k) {
if (n == 2 * k + 1) {
return 1;
}
}
return 0;
}
Let C-integers denote the possible values of int
in a given C compilation. (Note that C-integers is a subset of the integers.)
在给定的C编译中,让C-integer表示int的可能值。(注意,c -integer是整数的一个子集。)
Now one might worry that for a given n in C-integers that the corresponding integer k might not exist within C-integers. But with a little proof it is can be shown that for all integers n, |n| <= |2n| (*), where |n| is "n if n is positive and -n otherwise". In other words, for all n in integers at least one of the following holds (exactly either cases (1 and 2) or cases (3 and 4) in fact but I won't prove it here):
现在有人可能会担心,对于给定的n,在c整数中,对应的整数k可能不存在于c整数中。但是,有一点证明可以证明,对于所有整数n, |n| <= |2n|(*),其中|n|是“n如果n是正的,否则是-n”。换句话说,对于所有n的整数,至少有一种情况是这样的(1和2)或者情况(3和4),但我不会在这里证明它):
Case 1: n <= 2n.
案例1:n <= 2n。
Case 2: -n <= -2n.
情形2:-n <= -2n。
Case 3: -n <= 2n.
案例3:-n <= 2n。
Case 4: n <= -2n.
案例4:n <= -2n。
Now take 2k = n. (Such a k does exist if n is even, but I won't prove it here. If n is not even then the loop in even
fails to return early anyway, so it doesn't matter.) But this implies k < n if n not 0 by (*) and the fact (again not proven here) that for all m, z in integers 2m = z implies z not equal to m given m is not 0. In the case n is 0, 2*0 = 0 so 0 is even we are done (if n = 0 then 0 is in C-integers because n is in C-integer in the function even
, hence k = 0 is in C-integers). Thus such a k in C-integers exists for n in C-integers if n is even.
现在取2k = n(如果n是偶数,那么k是存在的,但这里我不证明它。如果n不是偶数,那么循环甚至不能提前返回,所以没关系。但这意味着k < n如果n不是0(*)和这个事实(这里还没有证明)对于所有m, z的整数2m = z意味着z不等于m,因为m不是0。在这个例子中,n = 0, 2*0 = 0,所以0是偶数,如果n = 0,那么0是c整数,因为n在函数中是c整数,因此k = 0是c -整数。因此,如果n是偶数,那么c -整数中的k是存在的。
A similar argument shows that if n is odd, there exists a k in C-integers such that n = 2k + 1.
一个类似的论证表明,如果n是奇数,那么在c整数中存在一个k,这样n = 2k + 1。
Hence the functions even
and odd
presented here will work properly for all C-integers.
因此,这里给出的函数甚至是奇数,都适用于所有的c整数。
#12
5
// C#
bool isEven = ((i % 2) == 0);
#13
5
This is a follow up to the discussion with @RocketRoy regarding his answer, but it might be useful to anyone who wants to compare these results.
这是关于他的回答与@RocketRoy讨论的后续,但是对于任何想要比较这些结果的人来说,这可能是有用的。
tl;dr From what I've seen, Roy's approach ((0xFFFFFFFF == (x | 0xFFFFFFFE)
) is not completely optimized to x & 1
as the mod
approach, but in practice running times should turn out equal in all cases.
从我所看到的来看,Roy的方法((0xFFFFFFFF == (x | 0xFFFFFFFE))并没有完全优化到x & 1作为mod方法,但是在实际运行中,在所有情况下都应该是相同的。
So, first I compared the compiled output using Compiler Explorer:
所以,首先我使用编译器浏览器比较编译后的输出:
Functions tested:
功能测试:
int isOdd_mod(unsigned x) {
return (x % 2);
}
int isOdd_and(unsigned x) {
return (x & 1);
}
int isOdd_or(unsigned x) {
return (0xFFFFFFFF == (x | 0xFFFFFFFE));
}
CLang 3.9.0 with -O3:
铿锵声3.9.0 o3:
isOdd_mod(unsigned int): # @isOdd_mod(unsigned int)
and edi, 1
mov eax, edi
ret
isOdd_and(unsigned int): # @isOdd_and(unsigned int)
and edi, 1
mov eax, edi
ret
isOdd_or(unsigned int): # @isOdd_or(unsigned int)
and edi, 1
mov eax, edi
ret
GCC 6.2 with -O3:
GCC 6.2 o3:
isOdd_mod(unsigned int):
mov eax, edi
and eax, 1
ret
isOdd_and(unsigned int):
mov eax, edi
and eax, 1
ret
isOdd_or(unsigned int):
or edi, -2
xor eax, eax
cmp edi, -1
sete al
ret
Hats down to CLang, it realized that all three cases are functionally equal. However, Roy's approach isn't optimized in GCC, so YMMV.
向CLang致敬,它意识到这三个案例在功能上是平等的。然而,在GCC中,Roy的方法并没有得到优化,所以YMMV。
It's similar with Visual Studio; inspecting the disassembly Release x64 (VS2015) for these three functions, I could see that the comparison part is equal for "mod" and "and" cases, and slightly larger for the Roy's "or" case:
它与Visual Studio相似;检查disassembly Release x64 (VS2015)对于这三个函数,我可以看到比较部分等于“mod”和“and”的情况,对于Roy的“or”案例稍微大一点:
// x % 2
test bl,1
je (some address)
// x & 1
test bl,1
je (some address)
// Roy's bitwise or
mov eax,ebx
or eax,0FFFFFFFEh
cmp eax,0FFFFFFFFh
jne (some address)
However, after running an actual benchmark for comparing these three options (plain mod, bitwise or, bitwise and), results were completely equal (again, Visual Studio 2005 x86/x64, Release build, no debugger attached).
然而,在运行一个实际的基准来比较这三个选项(plain mod、bitwise或bitwise和)之后,结果是完全相同的(同样,Visual Studio 2005 x86/x64,发布版本,没有附加调试器)。
Release assembly uses the test
instruction for and
and mod
cases, while Roy's case uses the cmp eax,0FFFFFFFFh
approach, but it's heavily unrolled and optimized so there is no difference in practice.
发布程序集使用测试指令和mod案例,而Roy的案例使用cmp eax,0FFFFFFFFh方法,但是它是大量展开和优化的,所以在实践中没有区别。
My results after 20 runs (i7 3610QM, Windows 10 power plan set to High Performance):
我在20次运行后的结果(i7 3610QM, Windows 10 power plan设置为高性能):
[Test: Plain mod 2 ] AVERAGE TIME: 689.29 ms (Relative diff.: +0.000%) [Test: Bitwise or ] AVERAGE TIME: 689.63 ms (Relative diff.: +0.048%) [Test: Bitwise and ] AVERAGE TIME: 687.80 ms (Relative diff.: -0.217%)
The difference between these options is less than 0.3%, so it's rather obvious the assembly is equal in all cases.
这些选项之间的差异小于0.3%,所以很明显,在所有情况下程序集都是相等的。
Here is the code if anyone wants to try, with a caveat that I only tested it on Windows (check the #if LINUX
conditional for the get_time
definition and implement it if needed, taken from this answer).
这里是代码,如果有人想尝试,我只在Windows上测试过它(如果需要的话,请检查#if LINUX条件是否为get_time定义并在需要时实现它)。
#include <stdio.h>
#if LINUX
#include <sys/time.h>
#include <sys/resource.h>
double get_time()
{
struct timeval t;
struct timezone tzp;
gettimeofday(&t, &tzp);
return t.tv_sec + t.tv_usec*1e-6;
}
#else
#include <windows.h>
double get_time()
{
LARGE_INTEGER t, f;
QueryPerformanceCounter(&t);
QueryPerformanceFrequency(&f);
return (double)t.QuadPart / (double)f.QuadPart * 1000.0;
}
#endif
#define NUM_ITERATIONS (1000 * 1000 * 1000)
// using a macro to avoid function call overhead
#define Benchmark(accumulator, name, operation) { \
double startTime = get_time(); \
double dummySum = 0.0, elapsed; \
int x; \
for (x = 0; x < NUM_ITERATIONS; x++) { \
if (operation) dummySum += x; \
} \
elapsed = get_time() - startTime; \
accumulator += elapsed; \
if (dummySum > 2000) \
printf("[Test: %-12s] %0.2f ms\r\n", name, elapsed); \
}
void DumpAverage(char *test, double totalTime, double reference)
{
printf("[Test: %-12s] AVERAGE TIME: %0.2f ms (Relative diff.: %+6.3f%%)\r\n",
test, totalTime, (totalTime - reference) / reference * 100.0);
}
int main(void)
{
int repeats = 20;
double runningTimes[3] = { 0 };
int k;
for (k = 0; k < repeats; k++) {
printf("Run %d of %d...\r\n", k + 1, repeats);
Benchmark(runningTimes[0], "Plain mod 2", (x % 2));
Benchmark(runningTimes[1], "Bitwise or", (0xFFFFFFFF == (x | 0xFFFFFFFE)));
Benchmark(runningTimes[2], "Bitwise and", (x & 1));
}
{
double reference = runningTimes[0] / repeats;
printf("\r\n");
DumpAverage("Plain mod 2", runningTimes[0] / repeats, reference);
DumpAverage("Bitwise or", runningTimes[1] / repeats, reference);
DumpAverage("Bitwise and", runningTimes[2] / repeats, reference);
}
getchar();
return 0;
}
#14
4
Here is an answer in Java:
下面是Java的一个答案:
public static boolean isEven (Integer Number) {
Pattern number = Pattern.compile("^.*?(?:[02]|8|(?:6|4))$");
String num = Number.toString(Number);
Boolean numbr = new Boolean(number.matcher(num).matches());
return numbr.booleanValue();
}
#15
4
As some people have posted, there are numerous ways to do this. According to this website, the fastest way is the modulus operator:
正如一些人发布的,有很多方法可以做到这一点。根据这个网站,最快的方法是模量算符:
if (x % 2 == 0)
total += 1; //even number
else
total -= 1; //odd number
However, here is some other code that was bench marked by the author which ran slower than the common modulus operation above:
但是,这里还有一些其他的代码,是由作者标记的,其运行速度比上面的普通模量操作要慢:
if ((x & 1) == 0)
total += 1; //even number
else
total -= 1; //odd number
System.Math.DivRem((long)x, (long)2, out outvalue);
if ( outvalue == 0)
total += 1; //even number
else
total -= 1; //odd number
if (((x / 2) * 2) == x)
total += 1; //even number
else
total -= 1; //odd number
if (((x >> 1) << 1) == x)
total += 1; //even number
else
total -= 1; //odd number
while (index > 1)
index -= 2;
if (index == 0)
total += 1; //even number
else
total -= 1; //odd number
tempstr = x.ToString();
index = tempstr.Length - 1;
//this assumes base 10
if (tempstr[index] == '0' || tempstr[index] == '2' || tempstr[index] == '4' || tempstr[index] == '6' || tempstr[index] == '8')
total += 1; //even number
else
total -= 1; //odd number
How many people even knew of the Math.System.DivRem method or why would they use it??
有多少人知道这个数学系统。他们为什么要用这个方法?
#16
4
Try this: return (((a>>1)<<1) == a)
试试这个:return((一个>>1)<<1)== a)
Example:
例子:
a = 10101011
-----------------
a>>1 --> 01010101
a<<1 --> 10101010
b = 10011100
-----------------
b>>1 --> 01001110
b<<1 --> 10011100
#17
4
Reading this rather entertaining discussion, I remembered that I had a real-world, time-sensitive function that tested for odd and even numbers inside the main loop. It's an integer power function, posted elsewhere on *, as follows. The benchmarks were quite surprising. At least in this real-world function, modulo is slower, and significantly so. The winner, by a wide margin, requiring 67% of modulo's time, is an or ( | ) approach, and is nowhere to be found elsewhere on this page.
阅读这篇有趣的讨论,我记得我有一个真实的、时间敏感的函数,它在主循环中测试奇数和偶数。它是一个整数幂函数,发布在*的其他地方,如下所示。基准测试非常令人吃惊。至少在这个现实世界的函数中,模块化是比较慢的,而且是显著的。胜出者,以很大的差距,需要67%的模组时间,是一个或(|)方法,并且在这一页的其他地方找不到。
static dbl IntPow(dbl st0, int x) {
UINT OrMask = UINT_MAX -1;
dbl st1=1.0;
if(0==x) return (dbl)1.0;
while(1 != x) {
if (UINT_MAX == (x|OrMask)) { // if LSB is 1...
//if(x & 1) {
//if(x % 2) {
st1 *= st0;
}
x = x >> 1; // shift x right 1 bit...
st0 *= st0;
}
return st1 * st0;
}
For 300 million loops, the benchmark timings are as follows.
对于3亿个循环,基准计时如下。
3.962 the | and mask approach
3.962 |和掩模方法。
4.851 the & approach
4.851 &方法
5.850 the % approach
5.850 %的方法
For people who think theory, or an assembly language listing, settles arguments like these, this should be a cautionary tale. There are more things in heaven and earth, Horatio, than are dreamt of in your philosophy.
对于那些认为理论或汇编语言清单的人来说,这应该是一个警示的故事。天地间有更多的东西,荷瑞修,比你的哲学所梦想的还要多。
#18
3
I know this is just syntactic sugar and only applicable in .net but what about extension method...
我知道这只是语法糖,只适用于。net,但是扩展方法……
public static class RudiGroblerExtensions
{
public static bool IsOdd(this int i)
{
return ((i % 2) != 0);
}
}
Now you can do the following
现在您可以执行以下操作。
int i = 5;
if (i.IsOdd())
{
// Do something...
}
#19
3
In the "creative but confusing category" I offer:
在“创造性但令人困惑的类别”中,我提供:
int isOdd(int n) { return n ^ n * n ? isOdd(n * n) : n; }
A variant on this theme that is specific to Microsoft C++:
这个主题的一个变体是针对微软c++的:
__declspec(naked) bool __fastcall isOdd(const int x)
{
__asm
{
mov eax,ecx
mul eax
mul eax
mul eax
mul eax
mul eax
mul eax
ret
}
}
#20
2
The bitwise method depends on the inner representation of the integer. Modulo will work anywhere there is a modulo operator. For example, some systems actually use the low level bits for tagging (like dynamic languages), so the raw x & 1 won't actually work in that case.
位方法依赖于整数的内部表示。Modulo在任何地方都可以工作。例如,有些系统实际上使用低级别的标记(比如动态语言),因此原始的x & 1在这种情况下不会实际工作。
#21
2
IsOdd(int x) { return true; }
IsOdd(int x){返回true;}
Proof of correctness - consider the set of all positive integers and suppose there is a non-empty set of integers that are not odd. Because positive integers are well-ordered, there will be a smallest not odd number, which in itself is pretty odd, so clearly that number can't be in the set. Therefore this set cannot be non-empty. Repeat for negative integers except look for the greatest not odd number.
正确性的证明——考虑所有正整数的集合,假设有一个非空的整数集,它们并不奇怪。因为正整数是有序的,所以会有一个最小的不是奇数,这本身是很奇怪的,所以很明显这个数不能在集合中,所以这个集合不能是非空的。对负整数重复,除了寻找最大的不是奇数。
#22
2
Portable:
便携式:
i % 2 ? odd : even;
Unportable:
Unportable:
i & 1 ? odd : even;
i << (BITS_PER_INT - 1) ? odd : even;
#23
1
int isOdd(int i){
return(i % 2);
}
done.
完成了。
#24
1
To give more elaboration on the bitwise operator method for those of us who didn't do much boolean algebra during our studies, here is an explanation. Probably not of much use to the OP, but I felt like making it clear why NUMBER & 1 works.
为了更详细地说明我们在学习过程中没有做大量布尔代数的人,这里有一个解释。可能对OP没有多大用处,但我想清楚为什么数字和1可以工作。
Please note like as someone answered above, the way negative numbers are represented can stop this method working. In fact it can even break the modulo operator method too since each language can differ in how it deals with negative operands.
请注意,就像有人在上面回答的那样,负数的表示方式可以阻止这个方法的工作。事实上,它甚至可以打破模运算符的方法,因为每种语言在处理负操作数时都有不同。
However if you know that NUMBER will always be positive, this works well.
然而,如果你知道这个数字永远是正数,这就很有效。
As Tooony above made the point that only the last digit in binary (and denary) is important.
正如图奥尼所指出的那样,只有二进制(和denary)中的最后一个数字是重要的。
A boolean logic AND gate dictates that both inputs have to be a 1 (or high voltage) for 1 to be returned.
布尔逻辑和gate规定,两个输入必须是1(或高电压)才能返回。
1 & 0 = 0.
1 & 0 = 0。
0 & 1 = 0.
0和1 = 0。
0 & 0 = 0.
0和0 = 0。
1 & 1 = 1.
1 & 1 = 1。
If you represent any number as binary (I have used an 8 bit representation here), odd numbers have 1 at the end, even numbers have 0.
如果你把任意数字表示为二进制(我在这里用了8位表示),奇数的末尾有1,偶数是0。
For example:
例如:
1 = 00000001
1 = 00000001
2 = 00000010
2 = 00000010
3 = 00000011
3 = 00000011
4 = 00000100
4 = 00000100
If you take any number and use bitwise AND (& in java) it by 1 it will either return 00000001, = 1 meaning the number is odd. Or 00000000 = 0, meaning the number is even.
如果你取任意一个数字并使用bitwise和(& in java),它将返回00000001,= 1表示这个数字是奇数。或者00000000 = 0,也就是说这个数是偶数。
E.g
如
Is odd?
很奇怪吗?
1 & 1 =
1 & 1 =
00000001 &
00000001 &
00000001 =
00000001 =
00000001 <— Odd
00000001 <余< p>
2 & 1 =
2和1 =
00000010 &
00000010 &
00000001 =
00000001 =
00000000 <— Even
00000000 <——甚至
54 & 1 =
54 & 1 =
00000001 &
00000001 &
00110110 =
00110110 =
00000000 <— Even
00000000 <——甚至
This is why this works:
这就是为什么这样做的原因:
if(number & 1){
//Number is odd
} else {
//Number is even
}
Sorry if this is redundant.
抱歉,这是多余的。
#25
1
Number Zero parity | zero http://tinyurl.com/oexhr3k
数字0对等| 0 http://tinyurl.com/oexhr3k。
Python code sequence.
Python代码序列。
# defining function for number parity check
def parity(number):
"""Parity check function"""
# if number is 0 (zero) return 'Zero neither ODD nor EVEN',
# otherwise number&1, checking last bit, if 0, then EVEN,
# if 1, then ODD.
return (number == 0 and 'Zero neither ODD nor EVEN') \
or (number&1 and 'ODD' or 'EVEN')
# cycle trough numbers from 0 to 13
for number in range(0, 14):
print "{0:>4} : {0:08b} : {1:}".format(number, parity(number))
Output:
输出:
0 : 00000000 : Zero neither ODD nor EVEN
1 : 00000001 : ODD
2 : 00000010 : EVEN
3 : 00000011 : ODD
4 : 00000100 : EVEN
5 : 00000101 : ODD
6 : 00000110 : EVEN
7 : 00000111 : ODD
8 : 00001000 : EVEN
9 : 00001001 : ODD
10 : 00001010 : EVEN
11 : 00001011 : ODD
12 : 00001100 : EVEN
13 : 00001101 : ODD
#26
1
I execute this code for ODD & EVEN:
#include <stdio.h>
int main()
{
int number;
printf("Enter an integer: ");
scanf("%d", &number);
if(number % 2 == 0)
printf("%d is even.", number);
else
printf("%d is odd.", number);
}
#27
0
For the sake of discussion...
为了讨论……
You only need to look at the last digit in any given number to see if it is even or odd. Signed, unsigned, positive, negative - they are all the same with regards to this. So this should work all round: -
你只需要看一个给定数字的最后一个数字,看看它是偶数还是奇数。签名,无符号,正面,负面-这些都是一样的。因此,这应该是一个全面的工作:-。
void tellMeIfItIsAnOddNumberPlease(int iToTest){
int iLastDigit;
iLastDigit = iToTest - (iToTest / 10 * 10);
if (iLastDigit % 2 == 0){
printf("The number %d is even!\n", iToTest);
} else {
printf("The number %d is odd!\n", iToTest);
}
}
The key here is in the third line of code, the division operator performs an integer division, so that result are missing the fraction part of the result. So for example 222 / 10 will give 22 as a result. Then multiply it again with 10 and you have 220. Subtract that from the original 222 and you end up with 2, which by magic is the same number as the last digit in the original number. ;-) The parenthesis are there to remind us of the order the calculation is done in. First do the division and the multiplication, then subtract the result from the original number. We could leave them out, since the priority is higher for division and multiplication than of subtraction, but this gives us "more readable" code.
这里的关键是在第三行代码中,除法运算符执行一个整数除法,所以结果会忽略掉分数部分。比如222 / 10,结果是22。再乘以10,得到220。从原来的222减去它,最后得到2,它和原来的数字是一样的。括号是用来提醒我们计算所做的顺序的。首先做除法和乘法运算,然后减去原数的结果。我们可以省略它们,因为优先级比减法要高,但这给了我们“更可读”的代码。
We could make it all completely unreadable if we wanted to. It would make no difference whatsoever for a modern compiler: -
如果我们想的话,我们可以让它完全无法读懂。对于一个现代的编译器来说,它是没有任何区别的:-。
printf("%d%s\n",iToTest,0==(iToTest-iToTest/10*10)%2?" is even":" is odd");
But it would make the code way harder to maintain in the future. Just imagine that you would like to change the text for odd numbers to "is not even". Then someone else later on want to find out what changes you made and perform a svn diff or similar...
但这将使代码在将来更难维护。想象一下,你想要把奇数变成“甚至不是”。然后其他人想知道你做了什么改变并执行了svn diff或类似的…
If you are not worried about portability but more about speed, you could have a look at the least significant bit. If that bit is set to 1 it is an odd number, if it is 0 it's an even number. On a little endian system, like Intel's x86 architecture it would be something like this: -
如果您不担心可移植性,但更关心的是速度,那么您可以看一下最不重要的部分。如果这个位被设为1这是个奇数,如果是0,它就是偶数。在一个小的endian系统上,就像Intel的x86架构一样,它会是这样的:-。
if (iToTest & 1) {
// Even
} else {
// Odd
}
#28
0
If you want to be efficient, use bitwise operators (x & 1
), but if you want to be readable use modulo 2 (x % 2
)
如果您想要高效,请使用位操作符(x & 1),但是如果您想要具有可读的使用模块2 (x % 2)
#29
0
Checking even or odd is a simple task.
检查偶数或奇数是一项简单的任务。
We know that any number exactly divisible by 2 is even number else odd.
我们知道任何能被2整除的数都是奇数。
We just need to check divisibility of any number and for checking divisibility we use %
operator
我们只需要检查任何数字的可分割性,并检查可分度,我们使用%运算符。
Checking even odd using if else
检查偶数,用if else。
if(num%2 ==0)
{
printf("Even");
}
else
{
printf("Odd");
}
C program to check even or odd using if else
C程序检查偶数或奇数使用。
Using Conditional/Ternary operator
使用条件/三元操作符
(num%2 ==0) printf("Even") : printf("Odd");
C program to check even or odd using conditional operator.
C程序使用条件运算符检查偶数或奇数。
Using Bitwise operator
使用位操作符
if(num & 1)
{
printf("Odd");
}
else
{
printf("Even");
}
#30
-1
Modulus operator '%' can be used to check whether a number is odd or even.That is when a number is divided by 2 and if the remainder is 0 then its an even number else its an odd number.
模数运算符'%'可以用来检验一个数字是奇数还是偶数。也就是说,当一个数除以2,如果余数是0,那么它的偶数就是一个奇数。
#include <stdio.h>
int main()
{
int n;//using modulus operator
scanf("%d",&n);//take input n from STDIN
printf("%s",n%2==0?"Even":"Odd");//prints Even/Odd depending on n to STDOUT
return 0;
}
But using Bit manipulation is quite faster than the above method,so if you take a number and apply logically AND '&' to it ,if the answer is 1 then its even else its odd.That is basically we have to check the last bit of the number n in binary.If the last bit is 0 then n is even else its odd.
但是使用位操作的速度要比上面的方法快得多,所以如果你取一个数字,并在逻辑上和“&”上应用,如果答案是1,那么它的奇数也会是偶数。这就是我们要检查n在二进制中的最后一点。如果最后一点是0,那么n就是奇数。
for example : suppose N = 15 , in binary N = 1111 , now we AND it with 1
例如:假设N = 15,在二进制N = 1111中,现在我们和它是1。
1111
0001
&-----
0001
Since the result is 1 the number N=15 is Odd.
Again,suppose N = 8 , in binary N = 1000 , now we AND it with 1
因为结果是1 N=15是奇数。再一次,假设N = 8,在二进制N = 1000,现在是1。
1000
0001
&-----
0000
Since the result is 0 the number N=8 is Even.
因为结果是0,所以N=8是偶数。
#include <stdio.h>
int main()
{
int n;//using AND operator
scanf("%d",&n);//take input n from STDIN
printf("%s",n&1?"Odd":"Even");//prints Even/Odd depending on n to STDOUT
return 0;
}