/* 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;
}
/*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
}
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;
}
}
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;
}
让 C- 整数表示给定 C 编译中 int的可能值。(注意,C- 整数是整数的子集。)
现在,人们可能会担心,对于给定的 C- 整数 n,对应的整数 k 可能不存在于 C- 整数中。但是只要稍加证明,就可以证明对于所有整数 n,| n | < = | 2n | (*) ,其中 | n | 是“ n,如果 n 是正数,否则-n”。换句话说,对于整数中的所有 n,至少有以下一种情况(确切地说是情况(1和2)或情况(3和4) ,但我不会在这里证明它) :
案例1: n < = 2n。
案例2:-n < = -2 n。
案例3:-n < = 2n。
案例4: n < = -2 n。
现在取2k = n (如果 n 是偶数,这样的 k 确实存在,但我不会在这里证明。如果 n 不是偶数,那么 even中的循环无论如何都不会提前返回,所以没关系。)但是这意味着如果 n 不是0的话 k < n (*) ,并且事实上(这里也没有证明) ,对于所有的 m,整数中的 z,2m = z 意味着 z 不等于 m,给定 m 不等于0。在 n 为0的情况下,2 * 0 = 0,所以0是偶数(如果 n = 0,那么0是 C- 整数,因为在函数 even中 n 是 C- 整数,所以 k = 0是 C- 整数)。因此,如果 n 是偶数,则 C 整数中的 k 存在于 C 整数中的 n。
一个类似的论证表明,如果 n 是奇数,那么在 C- 整数中存在一个 k,使得 n = 2k + 1。
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
# 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))
产出:
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
#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;
}
但是使用比特操作要比上面的方法快得多,所以如果你取一个数字并逻辑地对它应用 AND’&’,如果答案是1,那么它的其他值就是奇数。也就是说我们必须检查二进制数字 n 的最后一位,如果最后一位是0,那么 n 就是奇数。
例如: 假设 N = 15,在二进制中 N = 1111,现在我们用1与它 AND
1111
0001
&-----
0001
因为结果是1,所以 N = 15是奇数
同样,假设 N = 8,在二进制 N = 1000中,现在我们用1 AND 它
1000
0001
&-----
0000
因为结果是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;
}
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:
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
海湾合作委员会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
它与 Visual Studio 类似; 在检查 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)
但是,在运行一个实际的基准测试来比较这三个选项(普通的 mod、按位或按位和)之后,结果是完全相同的(同样,Visual Studio 2005 x86/x64,发布版本,没有附加调试器)。
运行20次后的结果(i73610QM,Windows 10电源计划设置为 High Performance) :
[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%)
这些选项之间的差异小于0.3% ,因此很明显,在所有情况下组装是相等的。
如果有人想尝试的话,这里是代码,但是我只在 Windows 上测试过(检查 #if LINUX条件的 get_time定义,如果需要的话实现它,从 这个答案中获取)。
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);
}