C语言 查找数字是偶数还是奇数的最快方法是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2229107/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 04:25:55  来源:igfitidea点击:

What is the fastest way to find if a number is even or odd?

cmicro-optimization

提问by aks

What is the fastest way to find if a number is even or odd?

查找数字是偶数还是奇数的最快方法是什么?

回答by kennytm

It is pretty well known that

众所周知

static inline int is_odd_A(int x) { return x & 1; }

is more efficient than

static inline int is_odd_B(int x) { return x % 2; }

But with the optimizer on, will is_odd_Bbe no different from is_odd_A? No — with gcc-4.2 -O2, we get, (in ARM assembly):

但是在优化器开启的情况下,会不会is_odd_B有什么不同is_odd_A?不 - 用gcc-4.2 -O2,我们得到,(在 ARM 汇编中):

_is_odd_A:
    and r0, r0, #1
    bx  lr

_is_odd_B:
    mov r3, r0, lsr #31
    add r0, r0, r3
    and r0, r0, #1
    rsb r0, r3, r0
    bx  lr

We see that is_odd_Btakes 3 more instructions than is_odd_A, the main reason is because

我们看到is_odd_B比 多 3 条指令is_odd_A,主要原因是因为

((-1) % 2) == -1
((-1) & 1) ==  1

However, all the following versions will generate the same code as is_odd_A:

但是,以下所有版本都将生成与以下相同的代码is_odd_A

#include <stdbool.h>
static inline bool is_odd_D(int x) { return x % 2; }      // note the bool
static inline int  is_odd_E(int x) { return x % 2 != 0; } // note the !=

What does this mean? The optimizer is usually sophisticated enough that, for these simple stuff, the clearest code is enough to guarantee best efficiency.

这是什么意思?优化器通常足够复杂,对于这些简单的东西,最清晰的代码足以保证最佳效率

回答by AndiDog

Usual way to do it:

通常的做法:

int number = ...;
if(number % 2) { odd }
else { even }

Alternative:

选择:

int number = ...;
if(number & 1) { odd }
else { even }

Tested on GCC 3.3.1 and 4.3.2, both have about the same speed (without compiler optimization) as both result in the andinstruction (compiled on x86) - I know that using the divinstruction for modulo would be much slower, thus I didn't test it at all.

在 GCC 3.3.1 和 4.3.2 上测试,两者的速度大致相同(没有编译器优化),因为两者都导致and指令(在 x86 上编译) - 我知道使用div模指令会慢得多,因此我没有根本不用测试。

回答by digitalarbeiter

bool is_odd = number & 1;

回答by Vicky

if (x & 1) is true then it's odd, otherwise it's even.

如果 (x & 1) 为真,则为奇数,否则为偶数。

回答by Marcel

If it's an integer, probably by just checking the least significant bit. Zero would be counted as even though.

如果它是一个整数,可能只是通过检查最低有效位。零将被视为即使。

回答by lamas

int i=5;
if ( i%2 == 0 )
{
   // Even
} else {
   // Odd
}

回答by 0xfe

Check to see if the last bit is 1.

检查最后一位是否为 1。

int is_odd(int num) {
  return num & 1;
}

回答by John Bode

The portableway is to use the modulus operator %:

便携式的方法是使用模运算符%

if (x % 2 == 0) // number is even

If you knowthat you're only ever going to run on two's complement architectures, you can use a bitwise and:

如果您知道您只会在二进制补码架构上运行,您可以使用按位和:

if (x & 0x01 == 0) // number is even

Using the modulus operator can result in slower code relative to the bitwise and; however, I'd stick with it unless all of the following are true:

相对于按位和,使用模数运算符会导致代码变慢;但是,除非以下所有情况都为真,否则我会坚持下去:

  1. You are failing to meet a hard performance requirement;
  2. You are executing x % 2a lot(say in a tight loop that's being executed thousands of times);
  3. Profiling indicates that usage of the mod operator is the bottleneck;
  4. Profiling also indicates that using the bitwise-and relieves the bottleneck andallows you to meet the performance requirement.
  1. 您未能满足严格的性能要求;
  2. 您正在执行x % 2一个不少(比如在一个紧密循环,就是BEING执行数千次);
  3. 分析表明 mod 运算符的使用是瓶颈;
  4. 分析还表明,使用按位和可以缓解瓶颈让您满足性能要求。

回答by jason

Your question is not completely specified. Regardless, the answer is dependent on your compiler and the architecture of your machine. For example, are you on a machine using one's complement or two's complement signed number representations?

你的问题没有完全说明。无论如何,答案取决于您的编译器和机器的体系结构。例如,您是在使用一个补码还是二进制补码有符号数表示的机器上?

I write my code to be correct first, clear second, concise third and fast last. Therefore, I would code this routine as follows:

我写我的代码首先是正确的,其次是清晰的,第三是简洁的,最后是快速的。因此,我将此例程编码如下:

/* returns 0 if odd, 1 if even */
/* can use bool in C99 */
int IsEven(int n) {
    return n % 2 == 0;
}

This method is correct, it more clearly expresses the intent than testing the LSB, it's concise and, believe it or not, it is blazing fast. If and only if profiling told me that this method were a bottleneck in my application would I consider deviating from it.

这种方法是正确的,它比测试 LSB 更清楚地表达了意图,它简洁,不管你信不信,它的速度非常快。当且仅当分析告诉我这种方法是我的应用程序中的瓶颈时,我才会考虑偏离它。

回答by Maurits Rijk

int is_odd(int n)
{
   if (n == 0)
      return 0;
   else if (n == 1)
      return 1;
   else
      return !is_odd(n - 1);
}

Oh wait, you said fastestway, not funniest. My bad ;)

哦等等,你说的是最快的方式,而不是最有趣的。我的错 ;)

Above function only works for positive numbers of course.

以上函数当然只适用于正数。