查找数字是偶数还是奇数的最快方法是什么?
答案 0 :(得分:54)
众所周知
static inline int is_odd_A(int x) { return x & 1; }
比
更有效static inline int is_odd_B(int x) { return x % 2; }
但是启用优化器后,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
我们发现is_odd_B
比is_odd_A
多了3个指令,主要原因是因为
((-1) % 2) == -1
((-1) & 1) == 1
但,以下所有版本都会生成与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 !=
这是什么意思?优化器通常足够复杂,对于这些简单的东西,最清晰的代码足以保证最佳效率。
答案 1 :(得分:7)
通常的做法:
int number = ...;
if(number % 2) { odd }
else { even }
替代:
int number = ...;
if(number & 1) { odd }
else { even }
在GCC 3.3.1和4.3.2上测试,两者都具有大约相同的速度(没有编译器优化),因为两者都导致and
指令(在x86上编译) - 我知道使用{{1对模数的指令要慢得多,因此我根本没有测试它。
答案 2 :(得分:6)
bool is_odd = number & 1;
答案 3 :(得分:5)
如果(x&amp; 1)为真,那么它是奇数,否则它是偶数。
答案 4 :(得分:2)
int i=5;
if ( i%2 == 0 )
{
// Even
} else {
// Odd
}
答案 5 :(得分:2)
如果它是一个整数,可能只需要检查最低有效位。即使如此,零也算在内。
答案 6 :(得分:2)
检查最后一位是否为1。
int is_odd(int num) {
return num & 1;
}
答案 7 :(得分:2)
portable 方式是使用模数运算符%
:
if (x % 2 == 0) // number is even
如果你知道你只会在两个补码架构上运行,你可以使用按位和:
if (x & 0x01 == 0) // number is even
使用模数运算符会导致相对于按位的代码更慢;但是,除非满足以下所有条件,否则我会坚持下去:
x % 2
一个批次(比如在一个被执行数千次的紧密循环中); 答案 8 :(得分:1)
您的问题尚未完全说明。无论如何,答案取决于您的编译器和机器的体系结构。例如,您是使用一个补码还是两个补码有符号数表示的机器?
我编写的代码首先是正确的,第二个是清晰的,第三个是简洁的,最后是快速的。因此,我会按如下方式编写此例程:
/* returns 0 if odd, 1 if even */
/* can use bool in C99 */
int IsEven(int n) {
return n % 2 == 0;
}
这种方法是正确的,它比测试LSB更清楚地表达了意图,它简洁,不管你信不信,它的速度非常快。当且仅当分析告诉我这个方法是我的应用程序的瓶颈时,我会考虑偏离它。
答案 9 :(得分:1)
int is_odd(int n)
{
if (n == 0)
return 0;
else if (n == 1)
return 1;
else
return !is_odd(n - 1);
}
哦等等,你说最快的方式,而不是最有趣的。我的坏;)
以上功能当然仅适用于正数。
答案 10 :(得分:0)
检查最低有效位:
if (number & 0x01) {
// It's odd
} else {
// It's even
}