C 找出一个数字是偶数还是奇数的最快方法是什么?
找出一个数字是偶数还是奇数的最快方法是什么?如果(x&1)为真,那么它是奇数,否则它是偶数。如果(x&1)为真,那么它是奇数,否则它是偶数。如果它是整数,可能只需检查最低有效位即可。如果零是整数,可能只需检查最低有效位即可。零将被视为偶数。检查最后一位是否为1C 找出一个数字是偶数还是奇数的最快方法是什么?,c,micro-optimization,C,Micro Optimization,找出一个数字是偶数还是奇数的最快方法是什么?如果(x&1)为真,那么它是奇数,否则它是偶数。如果(x&1)为真,那么它是奇数,否则它是偶数。如果它是整数,可能只需检查最低有效位即可。如果零是整数,可能只需检查最低有效位即可。零将被视为偶数。检查最后一位是否为1 int i=5; if ( i%2 == 0 ) { // Even } else { // Odd } bool is_odd = number & 1; int is_odd(int num) { retu
int i=5;
if ( i%2 == 0 )
{
// Even
} else {
// Odd
}
bool is_odd = number & 1;
int is_odd(int num) {
return num & 1;
}
检查最后一位是否为1
int is_odd(int num) {
return num & 1;
}
检查最低有效位:
if (number & 0x01) {
// It's odd
} else {
// It's even
}
检查最低有效位:
if (number & 0x01) {
// It's odd
} else {
// It's even
}
通常的做法是:
int number = ...;
if(number % 2) { odd }
else { even }
备选方案:
int number = ...;
if(number & 1) { odd }
else { even }
在GCC 3.3.1和4.3.2上测试,两者的速度都差不多(没有编译器优化),因为和指令(在x86上编译)-我知道使用div
指令进行模运算会慢得多,因此我根本没有测试它。通常的方法是:
int number = ...;
if(number % 2) { odd }
else { even }
备选方案:
int number = ...;
if(number & 1) { odd }
else { even }
在GCC 3.3.1和4.3.2上测试,两者的速度都差不多(没有编译器优化),因为和指令(在x86上编译)-我知道使用div
指令进行模运算会慢得多,因此我根本没有测试它。你的问题没有完全明确。无论如何,答案取决于编译器和机器的体系结构。例如,您是在使用一个补码还是两个补码符号数字表示的机器上
我写我的代码首先是正确的,其次是清晰的,第三是简洁的,最后是快速的。因此,我将此例程编码如下:
/* returns 0 if odd, 1 if even */
/* can use bool in C99 */
int IsEven(int n) {
return n % 2 == 0;
}
这种方法是正确的,它比测试LSB更清楚地表达了意图,它很简洁,而且,信不信由你,它非常迅速。如果而且只有当分析告诉我这个方法是我的应用程序的一个瓶颈时,我会考虑偏离它。p> 您的问题没有完全指定。无论如何,答案取决于编译器和机器的体系结构。例如,您是在使用一个补码还是两个补码符号数字表示的机器上
int is_odd(int n)
{
if (n == 0)
return 0;
else if (n == 1)
return 1;
else
return !is_odd(n - 1);
}
我写我的代码首先是正确的,其次是清晰的,第三是简洁的,最后是快速的。因此,我将此例程编码如下:
/* returns 0 if odd, 1 if even */
/* can use bool in C99 */
int IsEven(int n) {
return n % 2 == 0;
}
这种方法是正确的,它比测试LSB更清楚地表达了意图,它很简洁,而且,信不信由你,它非常迅速。如果而且只有当分析告诉我这个方法是我的应用程序的一个瓶颈时,我会考虑偏离它。p>
int is_odd(int n)
{
if (n == 0)
return 0;
else if (n == 1)
return 1;
else
return !is_odd(n - 1);
}
哦,等等,你说的是最快的方式,不是最有趣的。我的错;)
当然,上述函数只适用于正数
哦,等等,你说的是最快的方式,不是最有趣的。我的错;)
上述函数当然只适用于正数。可移植的方法是使用模数运算符%
:
if (x % 2 == 0) // number is even
如果您知道只能在两个互补体系结构上运行,则可以使用按位and:
if (x & 0x01 == 0) // number is even
使用模运算符会导致相对于按位and的代码速度变慢;但是,我会坚持下去,除非以下所有情况都是正确的:
您未能满足严格的性能要求李>
您执行了很多次x%2
(比如在一个执行了数千次的紧密循环中)李>
分析表明mod操作符的使用是瓶颈李>
分析还表明,使用按位和可以缓解瓶颈,并允许您满足性能要求
可移植的方法是使用模数运算符%
:
if (x % 2 == 0) // number is even
如果您知道只能在两个互补体系结构上运行,则可以使用按位and:
if (x & 0x01 == 0) // number is even
使用模运算符会导致相对于按位and的代码速度变慢;但是,我会坚持下去,除非以下所有情况都是正确的:
您未能满足严格的性能要求李>
您执行了很多次x%2
(比如在一个执行了数千次的紧密循环中)李>
分析表明mod操作符的使用是瓶颈李>
分析还表明,使用按位和可以缓解瓶颈,并允许您满足性能要求
众所周知
static inline int is_odd_A(int x) { return x & 1; }
它的效率比
static inline int is_odd_B(int x) { return x % 2; }
但是当优化器打开时,is\u odd\u B
是否与is\u odd\u A
没有区别?否-使用gcc-4.2-O2
,我们得到(臂内装配):
我们看到,is\u odd\u B
比is\u odd\u A
多占用3条指令,主要原因是
((-1) % 2) == -1
((-1) & 1) == 1
但是,以下所有版本将生成与is\u odd\u 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 !=
#包括
静态内联bool是奇数(intx){返回x%2;}//注意bool
静态内联int是奇数(intx){返回x%2!=0;}//注意=
这是什么意思?优化器通常非常复杂,对于这些简单的东西,最清晰的代码就足以保证最佳效率 众所周知
static inline int is_odd_A(int x) { return x & 1; }
它的效率比
static inline int is_odd_B(int x) { return x % 2; }
但是当优化器打开时,is\u odd\u B
是否与is\u odd\u A
没有区别?否-使用gcc-4.2-O2
,我们得到(臂内装配):
我们看到,is\u odd\u B
比is\u odd\u A
多占用3条指令,主要原因是
((-1) % 2) == -1
((-1) & 1) == 1
但是,以下所有版本将生成与is\u odd\u 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 !=
#包括
静态内联bool是奇数(intx){返回x%2;}//注意bool
静态内联int是奇数(intx){返回x%2!=0;}//注意=
这是什么意思?优化器通常非常复杂,对于这些简单的东西,最清晰的代码就足以保证最佳效率