Reputation: 577
I know a little C. I tried to write a program which uses no conditional statement but add odd numbers and multiply even numbers for a given array of integers. It was not very hard to write if odd add n else add 0 part. But, I couldn't work it out for the multiplication part. The solution seems to be multiply with 1 if odd else with n.
So, my question is given an integer, how you can transform it to 1 if it is odd else to the given integer. no conditional is allowed. Or, a better idea if possible. Thanks in advance.
Upvotes: 1
Views: 232
Reputation: 4762
Here's another multiplication-less version (that also assumes two's complement). The logic is to &
the number with with 11...11 (-1) for even numbers (11...1x where x is don't care would work too... maybe that could be used somehow) and with 00...01 for odd numbers. The problem then boils down to transforming odd and even numbers into those masks.
n&(((n&1) << 1) - 1)
(n&1) << 1
is 0 for even numbers and 2 for odd numbers. Subtracting one gives the desired masks.
(As said, you'd usually be better off doing n % 2 ? n : 1
rather than trying to second-guess the optimizer though. The compiler might generate a branchless conditional move for that if it thinks it's worthwhile.)
Upvotes: 0
Reputation: 26040
In other answers it was already pointed out that the indicator for odd and even is i%2
and (i+1)%2
.
You can use this to solve the full problem in one line:
result = (i%2)*(number+i)+((i+1)%2)*number*i
You have to care that i
is never negative. If that remains possible, then you can normalize the situation by a double mod operation: (2+i%2)%2
and (2+(i+1)%2)%2
.
Of course, using the branching this can be made shorter as in
result = (i%2)?(i+number):(i*number)
Upvotes: 0
Reputation: 241911
Without multiplication, assuming 2s complement arithmetic (cast i to unsigned if not):
/* implements odd(i) ? 1 : n */
(((i&1)-1)&(n-1)) + 1
Whether that's faster than multiplication depends heavily on architecture; on modern CPUs it's doubtful, but on embedded architectures it would be. It certainly is not faster than a compiler-generated conditional move, and it's hardly easy to read. Still...
Upvotes: 4
Reputation: 2817
res = (i % 2) ? 1: number;
Conditional execution, or, branch predication is the best shot.
Small branches are not so evil nowadays.
Edit It's branch predication, not branch prediction.
http://en.wikipedia.org/wiki/Branch_predication
Upvotes: 0
Reputation: 133
You can check last bit easily. This way, you know that number is odd or even.
last_bit = number & 0x01;
first_number = last_bit;
If last bit is zero, first number is zero. If not (odd), then it's 1.
Then you take last_bit and invert that last bit
last_bit = (last_bit+1) & 0x01;
second_number = last_bit * n;
Now second_number is either n or 0.
result = (first_number + second_number);
Upvotes: 2
Reputation: 20130
Ok, asked to provide an answer. Expression
res = (i % 2) + ((i+1) % 2) * number;
will return 1 if i
is odd, and given number
otherwise
Upvotes: 4
Reputation: 30146
There you go:
int Get1IfOddValOtherwise(int val)
{
return (1-(val&1))*(val-1)+1;
}
Upvotes: 1
Reputation: 75854
So let me shamelessly rip off the comment of @SeverinPappadeux and change it a little bit so I can claim it as my own:
res = i % 2 + (1 - i % 2) * number;
^^^^^ ^^^^^^^^^
odd: 1 0
even: 0 1
Upvotes: 2