Logic to check the number is divisible by 3 or not? - c

without using %, / or * , I have to find the no. is divisible by 3 or not?
it might be an interview question.
Thanks.

There are various ways. The simplest is pretty obvious:
int isdivby3(int n) {
if (n < 0) n = -n;
while (n > 0) n -= 3;
return n == 0;
}
But we can improve that. Any number can be represented like this: ("," means range inclusive):
Base2 (AKA binary)
(0,1) + 2*(0,1) + 4*(0,1)
Base4
(0,3) + 4*(0,3) + 16*(0,3)
BaseN
(0,N-1) + N*(0,N-1) + N*N*(0,N-1)
Now the trick is, a number x is divisible by n-1 if and only if the digitsum of x in base n is divisible by n-1. This trick is well-known for 9:
1926 = 6 + 2*10 + 9*100 + 1*1000
6+2+9+1 = 8 + 1*10
8+1 = 9 thus 1926 is divisible by 9
Now we can apply that for 3 too in base4. And were lucky since 4 is a power of 2 we can do binary bitwise operations. I use the notation number(base).
27(10) = 123(4)
Digitsum
12(4)
Digitsum again
3(4) = Divisible!
Now let's translate that to C:
int div3(int n) {
if (n < 0) n = -n;
else if (n == 0) return 1;
while (n > 3) {
int d = 0;
while (n > 0) {
d += n & 3;
n >>= 2;
}
n = d;
}
return n == 3;
}
Blazing fast.

Subtract 3 until you either
hit 0 - number was divisible by 3 (or)
get a number less than 0 - number wasn't divisible
if (number > 0)
{
while (number > 0)
{
number -= 3;
}
}
else if( number < 0)
{
while number < 0:
number += 3
}
return number == 0

Here is a reasonably efficient algorithm for large numbers. (Well not very efficient, but reasonable given the constraints.)
Use sprintf to convert it to a string, convert each digit back to a number. Add up the digits. If you come up with 3, 6, or 9, it is divisible by 3. Anything else less than 10, it is not. Anything over 9, recurse.
For instance to test the number 813478902 you'd stringify, then add the digits to get 42, add those digits to get 6, so it is divisible by 3.

just use a for loop subtracting 3 over and over and see if you get to 0. if you get to negative without getting to 0 then you know its not divisible by 3

To print a count sequence which is divisible by 3 without division or modulus operator.
Notice the count sequence:
00: 00(00)
01: 0001
02: 0010
03: 00(11)
04: 0100
05: 0101
06: 01(10)
07: 0111
08: 1000
09: 10(01)
10: 1010
11: 1011
12: 11(00)
13: 1101
14: 1110
15: 11(11)
16: 10000
17: 10001
18: 100(10)
19: 10011
20: 10100
21: 101(01)
Note that the last two bits of those numbers which are divisible by three (shown in brackets) are cycling through {00, 11, 10, 01} . What we need to check is if the last two bits of the count sequence has these bits in a sequence.
First we start matching with mask = 00 and loop while the first number is not encountered with the lower two bits 00. When a match is found we then do (mask + 03) & 0x03 which gets us the next mask in the set. And we continue to match the last two bits of the next count with 11. Which can be done by ((count & 3) == mask)
The code is
#include <stdio.h>
int main (void)
{
int i=0;
unsigned int mask = 0x00;
for (i=0; i<100;i++)
{
if ((i&0x03) == mask)
{
printf ("\n%d", i);
mask = (mask + 3) & 0x03;
}
}
printf ("\n");
return 0;
}
This is not a general one. Best is to use the solution which #nightcracker have suggested
Also if you really want to implement the division operation i without using the divide operations. I would tell you to have a look at the Non-Restoring Division Algorithm, this can be done in program with a lot of bit manipulations with bitwise operators. Here are some links and references for it.
Wikipedia Link
Here is a demo from UMass
Also have a look at Computer Organization by Carl Hamacher, Zvonko Vranesic, Safwat Zaky

number = abs(number)
while (number > 0)
{
number -= 3;
}
return number == 0

Suppose n is the number in question and it is non-negative.
If n is 0 it is divisible by 3; otherwise n = (2^p)*(2*n1+1) and n is divisible by 3 iff 2*n1+1 is, iff there is a k>=0 with 2*n1+1 = 3*(2*k+1) iff n1 = 3*k+1 iff n1=1 or n1> 1 and n1-1 is divisible by 3. So:
int ism3( int n)
{ for(;n;)
{ while( !(n & 1)) n >>= 1;
n >>= 1;
if ( n == 0) return 0;
n-= 1;
}
return 1;
}

The simplest way to know if a number is divisible by 3 is to sum all its digits and divide the result by 3. If the sum of the digits is divisible by 3, so the number itself is divisible by 3. For instance, 54467565687 is divisible by 3, because 5+4+4+6+7+5+6+5+6+8+7 = 63, and 63 is divisible by 3. So, no matter how big is the number, you can find if it is divisible by 3 just adding all its digits, and subtracting 3 from the value of this sum until you have a result smaller than 3. If this result is 0, the value of the sum is divisible by 3 (and so the original number), otherwise the sum is not divisible by 3 (and the original number is not divisible, either). It's done much more quickly than subtract 3 successively from the original number (of course, specially if it is a large number) and with no divisions. Um abraço a todos.
Artur

A number is divisible by three if its binary alternating digit sum is zero:
bool by3(int n) {
int s=0;
for (int q=1; n; s+=q*(n&1), n>>=1, q*=-1);
return !s;
}

You could use user feedback:
int isDivisibleBy3(int n)
{
int areDivisibleBy3[] = {};
for(int i = 0; i < 0; i++)
{
if(n == areDivisibleBy3[i])
{
return 1;
}
}
return 0;
}
When a user reports a bug stating that a number that is divisble by 3 is not giving the correct result, you simply add that number to the array and increase the number i is compared to in the for loop condition.
This is great because then you never have to worry about numbers the user never uses.
Don't forget to add a unit test for whenever a user reports a bug!

Related

C program that outputs if a number is divisble by 3 or not

I am new to programming, and I have to make an assignment in C. I have to make a program that reads an integer n and outputs if it is divisible by 3. Unfortunately I am not allowed to use the % operator to check this. "A positive integer is divisible by 3 if and only if the sum of all its digits is divisible by 3." So the program must add the digits of n, and if this is larger then 9, I have to add the digits of this number etc, until the sum of the digits is equal to or less then 9. Because then I am allowed to say whether n is divisible by 3 or not. I also have to print the number of the lose digits each time. For example: input:9999-----output:9999 -> 36 -> 9. YES.
I made a loop:
while(n>9){
lastDigit = n%10;
sumDigits += lastDigit;
n = (n-lastDigit)/10;
}
sumDigits = sumDigits + n; /*this is the sum of the digits*/
Now if this is larger then 9, I have to enter this number in the loop again, but I don't know how to do this. I made 3 other loops with if else statements, but that way my program is way to long. How can I make my program shorter? Because some numbers have to go through the loop multiple times.
Thanks.
Niek
You need two loops here - one that will loop as long as n > 9 and another to loop over the digits of n and sum them:
int origN = n;
while (n > 9) {
int sum = 0;
int tmp = n;
while (tmp > 0) {
int lastDigit = n % 10;
sum += lastDigit;
tmp /= 10;
}
n = sum;
}
if (n == 3 || n == 6 || n == 9) {
printf("%d is divisible by 3\n", origN);
} else {
printf("%d is not divisible by 3\n", origN);
}

combination of adding and subtracting of digits for specific value in C

Let´s say a number is called happy if there is any combination of addition and subtraction of the digits, ​​so that the result is 42.
Example:
9999993, 999399 and 399999 is happy because 9 + 9 + 9 + 9 + 9 - 3 = 42
3783985861 is also happy because: 3 + 7 + 8 − 3 + 9 + 8 − 5 + 8 + 6 + 1 = 42
My idea:
count how long the given number is
count the combinations: 2^n combinations | n = number length
for loop and check all combinations so that the result is 42
but how?????
do it recursively. I can do it by adding all digits. But how to check all
combinations?
int isHappy(unsigned int aNum){
int count = 0;
while(aNum != 0){
aNum /= 10;
count++;
}
int nTimes = 1;
for(int i=0;i<count;i++){
nTimes = nTimes * 2;
}
for(int i=0;i<nTimes;i++){
????
}
return nTimes;
}
int main(){
printf("%d", isHappy(999993));
return 0;
}
Posts that are certainly homework can benefit with some guiding code, but not too much - difficult to strike that balance.
For each digit, there are 2 ways to go, add the digit or subtract the digit. #Eugene Sh.. This is a classic consideration for a recursive solution. For an n-digit number, expect O(2**n) iterations.
Other approaches may be more efficient.
Avoid hard coding 42
#define HAPPY 42
Make a helper function that passes in the number and the current sum and returns success status.
What should the terminating condition be?
How to do some of the work?
How to try various paths for the rest of the task?
int isHappy_helper(unsigned int aNum, int sum) {
if (aNum == TBD) {
return sum == HAPPY;
}
// Extract one digit from aNum (how about the least significant digit?)
int digit = TBD;
// What is left in aNum once the above digit is removed?
aNum = TBD;
// Try adding and subtracting the digit with the sum
return isHappy_helper(aNum, TBD) || isHappy_helper(aNum, TBD);
}
Call the helper function with a sum of TBD
int isHappy(unsigned int aNum) {
return isHappy_helper(aNum, TBD);
}
Some test code
void isHappy_test(unsigned int aNum) {
printf("%u %d\n", aNum, isHappy(aNum));
}
int main() {
isHappy_test(0);
isHappy_test(1);
isHappy_test(9999993);
isHappy_test(999993);
isHappy_test(999399);
isHappy_test(399999);
isHappy_test(3783985861);
return 0;
}
Expected output
0 0
1 0
9999993 0
999993 1
999399 1
399999 1
3783985861 1

While loop iterates itself more or less than it should

Anwers of Austin Hastings and Michael Burr has solved my problem, this loop is always true as I just realised and it's solved when did it like Austin Hastings did. Cannot mark as answer since it is a comment. Thanks for your help!
I have an assignment in C which is to print only specific kinds of numbers between an 128 and 255 (so 8 digit binary representations) and I should do it without using any arithmetic operators. The conditions are:
Number's binary representation has to have same number of 0's and 1's.
Number's binary representation cannot have more 0's than 1's at any moment when reading from left-to-right. For example, 156 (1001 1100) does not meet the 2nd condition because there are two 0's and only one 1 at the 3rd digit, while 210 (1101 0010) satisfies these conditions.
I am using functional implementation and used a single function for these two conditions and that part of code is:
int checkOneToZero(unsigned int num) {
unsigned int carry = 7,
counterOne = 0,
counterZero = 0,
ct = 0;
while ((carry > 0) || (carry == 0)) {
if ((num >> carry) & 1) {
counterOne = binaryAddition(counterOne, 1);
ct ++;
printf(" %d ", ct);
}
else {
counterZero = binaryAddition(counterZero, 1);
ct ++;
printf(" %d ", ct);
}
carry = binarySubtraction(carry, 1);
printf(" CARRY %d \n", carry);
if (counterZero > counterOne) {
printf(" breakCounterZero %d breakCounterOne %d ", counterZero, counterOne);
return 0;
}
}
printf("successCounterZero = %d successCounterOne = %d", counterZero, counterOne);
if (counterZero == counterOne)
return 1;
return 0;
}
I had wrong output constantly so put some control mechanisms which do not effect the code to track the problem. These are:
ct : Counts how many times it has enter into if or else in while loop.
printf(" CARRY %d \n", carry) : shows carry's value after it has been decreased one.
printf(" breakCounterZero = &d breakCounterOne = %d ") : shows 0 and 1 counts if it has stuck at "if (counterZero > counterOne)" which checks 0 count cannot be higher than 1 count at the end of each while loop.
printf("successCounterZero = %d successCounterOne = %d") : shows if it has passed the while loop.
My problem is if I try to let while loop work until carry is used last with carry = 0, it gives output of 210, which should work as it loops 8 times and at CARRY = -1 it should break from the loop while it is like:
1 CARRY 6
2 CARRY 5
3 CARRY 4
4 CARRY 3
5 CARRY 2
6 CARRY 1
7 CARRY 0
8 CARRY -1
9 CARRY -2
breakCounterZero 5 breakCounterOne 4
so it loops 1 more time than it should and it makes count one more 0 so it fails. But wen I increased limit of carry to 1 in while loop to see what happens, it gives:
1 CARRY 6
2 CARRY 5
3 CARRY 4
4 CARRY 3
5 CARRY 2
6 CARRY 1
7 CARRY 0
successCounterZero = 3 successCounterOne = 4
so it passes the 3rd condition but one less 0 than it should so fails at 2nd condition.
This seems to be a complicated and a too-specific question, but thanks for any hints.
I'm not sure about your binaryAddition and binarySubtraction functions - whether you are required to use them, or simply are using them to meet the condition that no arithmetic operations be used.
For this simple case, it's worth pointing out that you can "count" up to 31 using the bits in an integer. Certainly enough to handle 8 possible values:
int checkOneToZero(unsigned num)
{
unsigned count_0s = 0;
unsigned count_1s = 0;
// Using a 'for' loop here because I know the start, stop, and update.
for (unsigned check_bit = 1 << 7; check_bit; check_bit >>= 1) {
if (num & check_bit) {
/* ++count_1s; */
count_1s |= (count_1s << 1) | 1;
}
else {
/* ++count_0s; */
count_0s |= (count_0s << 1) | 1;
if (count_0s > count_1s) return 0;
}
}
return count_0s == count_1s;
}

Sum of Digits using recursion in C

For our activity today, we were tasked to make using recursion with the sum of digits. I already made this program:
int main()
{
int num = 0, sum;
printf("Enter an integer: ");
scanf("%d",&num);
//counter=1;
for ( sum=0; num>0;)
{
sum = sum + num % 10;
num = num /10;
}
printf("Sum = %d", sum);
getch();
return 0;
}
Our teacher added "Input and output must be done in the main() function." Am doing the right thing? Or am I missing something in my code?
To do recursion, create a function that recurses rather than using a for loop.
int SumDigits(int i) {
if (i < 10) {
return i;
}
else {
return i%10 + SumDigits(i/10);
}
}
scanf("%d", &i);
printf("%d\n", SumDigits(i));
What you have there is an iterative solution, not a recursive one.
Recursion involves defining the problems in terms of a simpler version of the problem, all the time working towards a fixed end point.
The fixed end point in this case is any number less than 10, for which the value is that digit.
The transition to a simpler case (for numbers greater than 9) is simply to add the least significant digit to the result of the number divided by ten (integer division).
Since it's classwork, pseudo-code only I'm afraid.
def digitSum (n):
if n < 10:
return n
return (n % 10) + digitSum (n / 10)
If you follow that for the number 314, you'll see what happens.
At recursion level one, n == 314 so it calculates 314 % 10 to get 4 and calls digitSum(31).
At recursion level two, n == 31 so it calculates 31 % 10 to get 1 and calls digitSum(3).
At recursion level three, n == 3 so it just returns 3
Back up to level two, that's added to the remembered 1 and returned as 4.
Back up to level one, that's added to the remembered 4 and returned as 8.
Hence you end up with the digit sum of 8 for the number 314.

How do I check if an integer is even or odd? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Closed 4 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
How can I check if a given number is even or odd in C?
Use the modulo (%) operator to check if there's a remainder when dividing by 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.
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:
With no optimization flags.
With -O
With -Os
With -O2
With -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.
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.
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.
Of course, that doesn't work for negative numbers. But with brilliance comes sacrifice...
Use bit arithmetic:
if((x & 1) == 0)
printf("EVEN!\n");
else
printf("ODD!\n");
This is faster than using division or modulus.
[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.
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.
The C standard stipulates that negative numbers can be represented in 3 ways:
2's complement
1's complement
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.
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!
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 !
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.
// Java
public static boolean isOdd(int num){
return num % 2 != 0;
}
/* C */
int isOdd(int num){
return num % 2;
}
Methods are great!
i % 2 == 0
I'd say just divide it by 2 and if there is a 0 remainder, it's even, otherwise it's odd.
Using the modulus (%) makes this easy.
eg.
4 % 2 = 0 therefore 4 is even
5 % 2 = 1 therefore 5 is odd
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;
}
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:
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.
An integer n is odd if there exists an integer k such that 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.)
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):
Case 1: n <= 2n.
Case 2: -n <= -2n.
Case 3: -n <= 2n.
Case 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.
A similar argument shows that if n is odd, there exists a k in C-integers such that n = 2k + 1.
Hence the functions even and odd presented here will work properly for all C-integers.
// C#
bool isEven = ((i % 2) == 0);
Here is an answer in
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();
}
Try this: return (((a>>1)<<1) == a)
Example:
a = 10101011
-----------------
a>>1 --> 01010101
a<<1 --> 10101010
b = 10011100
-----------------
b>>1 --> 01001110
b<<1 --> 10011100
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 StackOverflow, 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.
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.962 the | and mask approach
4.851 the & approach
5.850 the % approach
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.
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.
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.
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:
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:
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.
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:
// 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).
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.
My results after 20 runs (i7 3610QM, Windows 10 power plan set to 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%)
The difference between these options is less than 0.3%, so it's rather obvious the assembly is equal in all cases.
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).
#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;
}
I know this is just syntactic sugar and only applicable in .net but what about extension method...
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...
}
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++:
__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
}
}
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.
IsOdd(int x) { return 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.
Portable:
i % 2 ? odd : even;
Unportable:
i & 1 ? odd : even;
i << (BITS_PER_INT - 1) ? odd : even;
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??
int isOdd(int i){
return(i % 2);
}
done.
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.
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.
A boolean logic AND gate dictates that both inputs have to be a 1 (or high voltage) for 1 to be returned.
1 & 0 = 0.
0 & 1 = 0.
0 & 0 = 0.
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.
For example:
1 = 00000001
2 = 00000010
3 = 00000011
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.
E.g
Is odd?
1 & 1 =
00000001 &
00000001 =
00000001 <— Odd
2 & 1 =
00000010 &
00000001 =
00000000 <— Even
54 & 1 =
00000001 &
00110110 =
00000000 <— Even
This is why this works:
if(number & 1){
//Number is odd
} else {
//Number is even
}
Sorry if this is redundant.
Number Zero parity | zero http://tinyurl.com/oexhr3k
Python code sequence.
# 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
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);
}
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.
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...
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: -
if (iToTest & 1) {
// Even
} else {
// Odd
}
If you want to be efficient, use bitwise operators (x & 1), but if you want to be readable use modulo 2 (x % 2)
Checking even or odd is a simple task.
We know that any number exactly divisible by 2 is even number else odd.
We just need to check divisibility of any number and for checking divisibility we use % operator
Checking even odd using if else
if(num%2 ==0)
{
printf("Even");
}
else
{
printf("Odd");
}
C program to check even or odd using if else
Using Conditional/Ternary operator
(num%2 ==0) printf("Even") : printf("Odd");
C program to check even or odd using conditional operator.
Using Bitwise operator
if(num & 1)
{
printf("Odd");
}
else
{
printf("Even");
}
+66% faster > !(i%2) / i%2 == 0
int isOdd(int n)
{
return n & 1;
}
The code checks the last bit of the integer if it's 1 in Binary
Explanation
Binary : Decimal
-------------------
0000 = 0
0001 = 1
0010 = 2
0011 = 3
0100 = 4
0101 = 5
0110 = 6
0111 = 7
1000 = 8
1001 = 9
and so on...
Notice the rightmost bit is always 1 for Odd numbers.
the & bitwise AND operator checks the rightmost bit in our return line if it's 1
Think of it as true & false
When we compare n with 1 which means 0001 in binary (number of zeros doesn't matter).
then let's just Imagine that we have the integer n with a size of 1 byte.
It'd be represented by 8-bit / 8-binary digits.
If the int n was 7 and we compare it with 1, It's like
7 (1-byte int)| 0 0 0 0 0 1 1 1
&
1 (1-byte int)| 0 0 0 0 0 0 0 1
********************************************
Result | F F F F F F F T
Which F stands for false and T for true.
It compares only the rightmost bit if they're both true. So, automagically 7 & 1 is True.
What if I want to check the bit before the rightmost?
Simply change n & 1 to n & 2 which 2 represents 0010 in Binary and so on.
I suggest using hexadecimal notation if you're a beginner to bitwise operations
return n & 1; >> return n & 0x01;.

Resources