I'm currently working through the K&R C book exercises and am on exercise 8 of chapter 2. The challenge is to write a function 'rotright' that rotates (or circle shifts) the bits of unsigned integer x by n bits. I believe I've come up with a solution, but it's not returning what I would expect. Given the number 213, which is 11010101 in binary, rotating 2 bits to the right would yield 01110101, which is 117. However, my program upon being given x=213 and n=2 returns 53. I've tried writing out the process of what's happening to the integer in binary form in comments and can't find a problem. Any help would be appreciated.
#include <stdio.h>
unsigned rotright(unsigned x, int n)
{
/* Example with x = 11010101 (213 in decimal), n = 2
First iteration:
x = (01101010) | ~(11111111 >> 1) = 11101010
Second iteration:
x = (01110101) | ~(11111111 >> 0) = 01110101
Returns 01110101
right shifts only if last bit of x == 1, then sets first bit of right shifted x to 1
if last bit of x == 0, x is right shifted by 1 and then unchanged.
(01101010) | ~(11111111 >> (11010101 & 00000001))
= 01101010 | ~(11111111 >> 00000001)
= 01101010 | 10000000 = 11101010
(11101010) | ~(11111111 >> (11101010 & 00000001))
= 01110101 | ~(11111111 >> 0)
= 01110101 | 00000000 = 01110101
*/
for (; n > 0; n--)
x = (x >> 1) | ~(~0 >> (x & 1));
return x;
}
int main()
{
printf("%d\n", rotright(213, 2));
return 0;
}
x = (x >> 1) | ~(~0 >> (x & 1));
you get 53 because this is (213 >> 2)
~(~0 >> (x & 1)) is always 0, because ~0 is -1, and (-1 >> n) is again -1 in your case, and finally ~(-1) is 0
You want that :
#include <stdio.h>
#include <limits.h>
unsigned rotright(unsigned x, int n)
{
unsigned mask = (1u << (CHAR_BIT * sizeof(int) - 1));
for (; n > 0; n--) {
x = (x / 2) | ((x & 1) ? mask : 0);
}
return x;
}
int main()
{
printf("%d\n", rotright(213, 2));
return 0;
}
On 32bits the result is 1073741877 being 1000000000000000000000000110101, not 117 whose supposes you work on 8 bits
Related
Suppose I have two 4-bit values, ABCD and abcd. How to interleave it, so it becomes AaBbCcDd, using bitwise operators? Example in pseudo-C:
nibble a = 0b1001;
nibble b = 0b1100;
char c = foo(a,b);
print_bits(c);
// output: 0b11010010
Note: 4 bits is just for illustration, I want to do this with two 32bit ints.
This is called the perfect shuffle operation, and it's discussed at length in the Bible Of Bit Bashing, Hacker's Delight by Henry Warren, section 7-2 "Shuffling Bits."
Assuming x is a 32-bit integer with a in its high-order 16 bits and b in its low-order 16 bits:
unsigned int x = (a << 16) | b; /* put a and b in place */
the following straightforward C-like code accomplishes the perfect shuffle:
x = (x & 0x0000FF00) << 8 | (x >> 8) & 0x0000FF00 | x & 0xFF0000FF;
x = (x & 0x00F000F0) << 4 | (x >> 4) & 0x00F000F0 | x & 0xF00FF00F;
x = (x & 0x0C0C0C0C) << 2 | (x >> 2) & 0x0C0C0C0C | x & 0xC3C3C3C3;
x = (x & 0x22222222) << 1 | (x >> 1) & 0x22222222 | x & 0x99999999;
He also gives an alternative form which is faster on some CPUs, and (I think) a little more clear and extensible:
unsigned int t; /* an intermediate, temporary variable */
t = (x ^ (x >> 8)) & 0x0000FF00; x = x ^ t ^ (t << 8);
t = (x ^ (x >> 4)) & 0x00F000F0; x = x ^ t ^ (t << 4);
t = (x ^ (x >> 2)) & 0x0C0C0C0C; x = x ^ t ^ (t << 2);
t = (x ^ (x >> 1)) & 0x22222222; x = x ^ t ^ (t << 1);
I see you have edited your question to ask for a 64-bit result from two 32-bit inputs. I'd have to think about how to extend Warren's technique. I think it wouldn't be too hard, but I'd have to give it some thought. If someone else wanted to start here and give a 64-bit version, I'd be happy to upvote them.
EDITED FOR 64 BITS
I extended the second solution to 64 bits in a straightforward way. First I doubled the length of each of the constants. Then I added a line at the beginning to swap adjacent double-bytes and intermix them. In the following 4 lines, which are pretty much the same as the 32-bit version, the first line swaps adjacent bytes and intermixes, the second line drops down to nibbles, the third line to double-bits, and the last line to single bits.
unsigned long long int t; /* an intermediate, temporary variable */
t = (x ^ (x >> 16)) & 0x00000000FFFF0000ull; x = x ^ t ^ (t << 16);
t = (x ^ (x >> 8)) & 0x0000FF000000FF00ull; x = x ^ t ^ (t << 8);
t = (x ^ (x >> 4)) & 0x00F000F000F000F0ull; x = x ^ t ^ (t << 4);
t = (x ^ (x >> 2)) & 0x0C0C0C0C0C0C0C0Cull; x = x ^ t ^ (t << 2);
t = (x ^ (x >> 1)) & 0x2222222222222222ull; x = x ^ t ^ (t << 1);
From Stanford "Bit Twiddling Hacks" page:
https://graphics.stanford.edu/~seander/bithacks.html#InterleaveTableObvious
uint32_t x = /*...*/, y = /*...*/;
uint64_t z = 0;
for (int i = 0; i < sizeof(x) * CHAR_BIT; i++) // unroll for more speed...
{
z |= (x & 1U << i) << i | (y & 1U << i) << (i + 1);
}
Look at the page they propose different and faster algorithms to achieve the same.
Like so:
#include <limits.h>
typedef unsigned int half;
typedef unsigned long long full;
full mix_bits(half a,half b)
{
full result = 0;
for (int i=0; i<sizeof(half)*CHAR_BIT; i++)
result |= (((a>>i)&1)<<(2*i+1))|(((b>>i)&1)<<(2*i+0));
return result;
}
Here is a loop-based solution that is hopefully more readable than some of the others already here.
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
uint64_t interleave(uint32_t a, uint32_t b) {
uint64_t result = 0;
int i;
for (i = 0; i < 31; i++) {
result |= (a >> (31 - i)) & 1;
result <<= 1;
result |= (b >> (31 - i)) & 1;
result <<= 1;
}
// Skip the last left shift.
result |= (a >> (31 - i)) & 1;
result <<= 1;
result |= (b >> (31 - i)) & 1;
return result;
}
void printBits(uint64_t a) {
int i;
for (i = 0; i < 64; i++)
printf("%lu", (a >> (63 - i)) & 1);
puts("");
}
int main(){
uint32_t a = 0x9;
uint32_t b = 0x6;
uint64_t c = interleave(a,b);
printBits(a);
printBits(b);
printBits(c);
}
I have used the 2 tricks/operations used in this post How do you set, clear, and toggle a single bit? of setting a bit at particular index and checking the bit at particular index.
The following code is implemented using these 2 operations only.
int a = 0b1001;
int b = 0b1100;
long int c=0;
int index; //To specify index of c
int bit,i;
//Set bits in c from right to left.
for(i=32;i>=0;i--)
{
index=2*i+1; //We have to add the bit in c at this index
//Check a
bit=a&(1<<i); //Checking whether the i-th bit is set in a
if(bit)
c|=1<<index; //Setting bit in c at index
index--;
//Check b
bit=b&(1<<i); //Checking whether the i-th bit is set in b
if(bit)
c|=1<<index; //Setting bit in c at index
}
printf("%ld",c);
Output: 210 which is 0b11010010
How do I return the number of consecutive ones on the left side of an integer using only bit operations in C (no if, for, while,etc.)?
I'm not sure where to begin for this problem.
//BurstSize(-1) = 32,
//BurstSize(0xFFF0F0F0) = 12
//Legal: ! ~ & ^ | + << >>
//Max ops: 50
int BurstSize(int a) {
//code
}
If you use GCC, you could call __builtin_clz() to count leading zeros. Invert the input, then it could be used to count leading ones.
int BurstSize(unsigned a) {
return __builtin_clz(~a);
}
If you cannot access __builtin_*(), then you can implement the leading zero counting function as in Hacker's Delight:
int nlz4(unsigned x) {
int y, m, n;
y = -(x >> 16); // If left half of x is 0,
m = (y >> 16) & 16; // set n = 16. If left half
n = 16 - m; // is nonzero, set n = 0 and
x = x >> m; // shift x right 16.
// Now x is of the form 0000xxxx.
y = x - 0x100; // If positions 8-15 are 0,
m = (y >> 16) & 8; // add 8 to n and shift x left 8.
n = n + m;
x = x << m;
y = x - 0x1000; // If positions 12-15 are 0,
m = (y >> 16) & 4; // add 4 to n and shift x left 4.
n = n + m;
x = x << m;
y = x - 0x4000; // If positions 14-15 are 0,
m = (y >> 16) & 2; // add 2 to n and shift x left 2.
n = n + m;
x = x << m;
y = x >> 14; // Set y = 0, 1, 2, or 3.
m = y & ~(y >> 1); // Set m = 0, 1, 2, or 2 resp.
return n + 2 - m;
}
int BurstSize(unsigned a) {
return nlz4(~a);
}
Easiest method: invert the number, then find the most significant bit set. The rest you can do yourself (I am 99% sure this is a homework question, so I am giving a hint only. If you really need more help, ask in the comments and I will expand further).
As for finding the most significant bit set, look at https://stackoverflow.com/a/21413883/1967396
for a fairly efficient method.
update Now for a complete method that finds the most significant bit set (after inverting), and then uses a clever lookup table to convert to actual byte (with a modulo 37 trick that didn't come from me... I found it at http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightModLookup but made a small change so it works for 32 bits set). I include code to test patterns from 0 to 32 bits - seems to work.
#include <stdio.h>
int burstSize(int n) {
// return number of consecutive bits set
unsigned int m, r;
m = ~n;
m = m | m >> 1;
m = m | m >> 2;
m = m | m >> 4;
m = m | m >> 8;
m = m | m >> 16;
m = ((m ^ (m >> 1)) | 0x80000000) & m;
static const int Mod37BitPosition[] = // map a bit value mod 37 to its position
{
-1, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4,
7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5,
20, 8, 19, 18
};
r = Mod37BitPosition[m % 37]; // <<<< not sure if this is allowed in your assignment...
return 31 - r; // <<< you could rewrite the LUT so you don't need an operation here. I was lazy.
}
int main(void) {
printf("%d\n", burstSize(0x00000000));
printf("%d\n", burstSize(0x80000000));
printf("%d\n", burstSize(0xC0000000));
printf("%d\n", burstSize(0xE0000000));
printf("%d\n", burstSize(0xF0000000));
printf("%d\n", burstSize(0xF8000000));
printf("%d\n", burstSize(0xFC000000));
printf("%d\n", burstSize(0xFE000000));
printf("%d\n", burstSize(0xFF000000));
printf("%d\n", burstSize(0xFF800000));
printf("%d\n", burstSize(0xFFC00000));
printf("%d\n", burstSize(0xFFE00000));
printf("%d\n", burstSize(0xFFF00000));
printf("%d\n", burstSize(0xFFF80000));
printf("%d\n", burstSize(0xFFFC0000));
printf("%d\n", burstSize(0xFFFE0000));
printf("%d\n", burstSize(0xFFFF0000));
printf("%d\n", burstSize(0xFFFFF800));
printf("%d\n", burstSize(0xFFFFFC00));
printf("%d\n", burstSize(0xFFFFFE00));
printf("%d\n", burstSize(0xFFFFFF00));
printf("%d\n", burstSize(0xFFFFFFF8));
printf("%d\n", burstSize(0xFFFFFFFC));
printf("%d\n", burstSize(0xFFFFFFFE));
printf("%d\n", burstSize(0xFFFFFFFF));
}
TRY THIS:
unsigned int A=0XFFF0; //your own number
unsigned int B0=(1 & A)/1;
unsigned int B1=(2 & A)/2;
unsigned int B2=(4 & A)/4;
unsigned int B3=(8 & A)/8;
unsigned int B4=(16 & A)/16;
unsigned int B5=(32 & A)/32;
unsigned int B6=(64 & A)/64;
unsigned int B7=(128 & A)/128;
unsigned int B8=(256 & A)/256;
unsigned int B9=(512 & A)/512;
unsigned int B10=(1024 & A)/1024;
unsigned int B11=(2048 & A)/2048;
unsigned int B12=(4096 & A)/4096;
unsigned int B13=(8192 & A)/8192;
unsigned int B14=(16384 & A)/16384;
unsigned int B15=(32768 & A)/32768;
int Result=B15+
B14*(B15)+
B13*(B14*B15)+
B12*(B13*B14*B15)+
B11*(B12*B13*B14*B15)+
B10*(B11*B12*B13*B14*B15)+
B9*(B10*B11*B12*B13*B14*B15)+
B8*(B9*B10*B11*B12*B13*B14*B15)+
B7*(B8*B9*B10*B11*B12*B13*B14*B15)+
B6*(B7*B8*B9*B10*B11*B12*B13*B14*B15)+
B5*(B6*B7*B8*B9*B10*B11*B12*B13*B14*B15)+
B4*(B5*B6*B7*B8*B9*B10*B11*B12*B13*B14*B15)+
B3*(B4*B5*B6*B7*B8*B9*B10*B11*B12*B13*B14*B15)+
B2*(B3*B4*B5*B6*B7*B8*B9*B10*B11*B12*B13*B14*B15)+
B1*(B2*B3*B4*B5*B6*B7*B8*B9*B10*B11*B12*B13*B14*B15)+
B0*(B1*B2*B3*B4*B5*B6*B7*B8*B9*B10*B11*B12*B13*B14*B15);
The following answer reverses the number to do the operation, it doesn't use the % operator, it uses one - sign though:
#include <iostream>
int burstSize(int n) {
// Reverse the bits
n = (n & 0x55555555) << 1 | (n & 0xAAAAAAAA) >> 1;
n = (n & 0x33333333) << 2 | (n & 0xCCCCCCCC) >> 2;
n = (n & 0x0F0F0F0F) << 4 | (n & 0xF0F0F0F0) >> 4;
n = (n & 0x00FF00FF) << 8 | (n & 0xFF00FF00) >> 8;
n = (n & 0x0000FFFF) << 16 | (n & 0xFFFF0000) >> 16;
// rightmost 0-bit, produces 0 if none (e.g., 10100111 -> 00001000)
int r = ~n & (n + 1);
// r - 1 will give us a mask of the consequtive 1s to isolate (e.g., 0100 -> 0011)
n = (r - 1) & n;
// Count the bits
n = (n & 0x55555555) + ((n >> 1) & 0x55555555);
n = (n & 0x33333333) + ((n >> 2) & 0x33333333);
n = (n & 0x0F0F0F0F) + ((n >> 4) & 0x0F0F0F0F);
n = (n & 0x00FF00FF) + ((n >> 8) & 0x00FF00FF);
n = (n & 0x0000FFFF) + ((n >>16) & 0x0000FFFF);
// Return the bit count
return n;
}
int main() {
std::cout << burstSize(0x00000000) << std::endl; // 0
std::cout << burstSize(0x00010F00) << std::endl; // 0
std::cout << burstSize(0x80010F00) << std::endl; // 1
std::cout << burstSize(0xF0010F00) << std::endl; // 4
std::cout << burstSize(0xFFFFFFFE) << std::endl; // 31
std::cout << burstSize(0xFFFFFFFF) << std::endl; // 32
return 0;
}
Here is the problem and what I currently have, I just don't understand how it is wrong...
getByte - Extract byte n from word x Bytes numbered from 0 (LSB) to
3 (MSB) Examples: getByte(0x12345678,1) = 0x56 Legal ops: ! ~ &
^ | + << >> Max ops: 6 Rating: 2
int getByte(int x, int n) {
return ((x << (24 - 8 * n)) >> (8 * n));
}
Your shifting doesn't make any sense - first, you shift left by (24 - 8n) bits, then you shift back right by 8n bits. Why? Also, it's wrong. If n is 0, you shift x left by 24 bits and return that value. Try pen and paper to see that this is entirely wrong.
The correct approach would be to do:
int getByte(int x, int n) {
return (x >> 8*n) & 0xFF;
}
Unless i am totally mistaken, your code is mathematically incorrect.
getByte(0x000000ff, 0) {
24 - 8 * n = 24;
8 * n = 0;
0x000000ff << 24 = 0xff000000;
0xff000000 >> 0 = 0xff000000;
return 0xff000000; // should return 0xff
}
Not being allowed to use operators - and especially * is a problem (can't do * 8). I came up with this:
uint8_t getByte (uint32_t x, int n) {
switch (n) {
case 0:
return x & 0xff;
case 1:
return (x >> 8) & 0xff;
case 2:
return (x >> 16) & 0xff;
case 3:
return x >> 24;
}
}
Not exactly beautiful, but it conforms to the problem description: 6 operators, all of them legal.
EDIT: Just had a (pretty obvious) idea for how to avoid * 8
uint8_t getByte (uint32_t x, int n) {
return (x >> (n << 3)) & 0xff;
}
I don't understand how your function works. Try this instead:
int getByte(int x, int n)
{
return (x >> (8 * n)) & 0xFF;
}
for example,if i have number 64,then its binary representation would be 0000 0000 0000 0000 0000 0000 0100 0000 so leading number of zero's is 25.
remember i have to calculate this in O(1) time.
please tell me the right way to do that.even if your complexity is >O(1) please do post your answer. thanx
I just found this problem at the top of the search results and this code:
int pop(unsigned x) {
unsigned n;
n = (x >> 1) & 033333333333;
x = x - n;
n = (n >> 1) & 033333333333;
x = x - n;
x = (x + (x >> 3)) & 030707070707;
return x % 63;
}
int nlz(unsigned x) {
x = x | (x >> 1);
x = x | (x >> 2);
x = x | (x >> 4);
x = x | (x >> 8);
x = x | (x >>16);
return pop(~x);
}
where pop counts 1 bits, is several times faster than the first (upvoted) answer.
I didn't notice, question was about 64 bits numbers, so here:
int nlz(unsigned long x) {
unsigned long y;
long n, c;
n = 64;
c = 32;
do {
y = x >> c;
if (y != 0) {
n = n - c;
x = y;
}
c = c >> 1;
} while (c != 0);
return n - x;
}
is a 64 bits algorithm, again several times faster than the mentioned above.
See here for the 32-bit version and other great bit-twiddling hacks.
// this is like doing a sign-extension
// if original value was 0x00.01yyy..y
// then afterwards will be 0x00.01111111
x |= (x >> 1);
x |= (x >> 2);
x |= (x >> 4);
x |= (x >> 8);
x |= (x >> 16);
x |= (x >> 32);
and after that you just need to return 64 - numOnes(x).
A simple way to do that is numOnes32(x) + numOnes32(x >> 32) where numOnes32 is defined as:
int numOnes32(unsigned int x) {
x -= ((x >> 1) & 0x55555555);
x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
x = (((x >> 4) + x) & 0x0f0f0f0f);
x += (x >> 8);
x += (x >> 16);
return(x & 0x0000003f);
}
I haven't tried out this code, but this should do numOnes64 directly (in less time):
int numOnes64(unsigned long int x) {
x = ((x >> 1) & 0x5555555555555555L) + (x & 0x5555555555555555L);
x = ((x >> 2) & 0x3333333333333333L) + (x & 0x3333333333333333L);
// collapse:
unsigned int v = (unsigned int) ((x >>> 32) + x);
v = ((v >> 4) + v) & 0x0f0f0f0f) + (v & 0x0f0f0f0f);
v = ((v >> 8) & 0x00ff00ff) + (v & 0x00ff00ff);
return ((v >> 16) & 0x0000ffff) + (v & 0x0000ffff);
}
Right shift is your friend.
int input = 64;
int sample = ( input < 0 ) ? 0 : input;
int leadingZeros = ( input < 0 ) ? 0 : 32;
while(sample) {
sample >>= 1;
--leadingZeros;
}
printf("Input = %d, leading zeroes = %d\n",input, leadingZeros);
I would go with:
unsigned long clz(unsigned long n) {
unsigned long result = 0;
unsigned long mask = 0;
mask = ~mask;
auto size = sizeof(n) * 8;
auto shift = size / 2;
mask >>= shift;
while (shift >= 1) {
if (n <= mask) {
result += shift;
n <<= shift;
}
shift /= 2;
mask <<= shift;
}
return result;
}
Because the logarithm base 2 roughly represents the number of bits required to represent a number, it might be useful in the answer:
irb(main):012:0> 31 - (Math::log(64) / Math::log(2)).floor()
=> 25
irb(main):013:0> 31 - (Math::log(65) / Math::log(2)).floor()
=> 25
irb(main):014:0> 31 - (Math::log(127) / Math::log(2)).floor()
=> 25
irb(main):015:0> 31 - (Math::log(128) / Math::log(2)).floor()
=> 24
Of course, one downside to using log(3) is that it is a floating-point routine; there are probably some supremely clever bit-tricks to find the number of leading zero bits in integers, but I can't think of one off the top of my head...
Using floating points is not the right answer....
Here is an algo that I use to count the TRAILING 0... change it for Leading...
This algo is in O(1) (will always execute in ~ the same time, or even the same time on some CPU).
int clz(unsigned int i)
{
int zeros;
if ((i&0xffff)==0) zeros= 16, i>>= 16; else zeroes= 0;
if ((i&0xff)==0) zeros+= 8, i>>= 8;
if ((i&0xf)==0) zeros+= 4, i>>= 4;
if ((i&0x3)==0) zeros+= 2, i>>= 2;
if ((i&0x1)==0) zeros+= 1, i>>= 1;
return zeroes+i;
}
Check whether a number x is nonzero using the legal operators except !.
Examples: isNonZero(3) = 1, isNonZero(0) = 0
Legal ops: ~ & ^ | + << >>
Note : Only bitwise operators should be used. if, else, for, etc. cannot be used.
Edit1 : No. of operators should not exceed 10.
Edit2 : Consider size of int to be 4 bytes.
int isNonZero(int x) {
return ???;
}
Using ! this would be trivial , but how do we do it without using ! ?
The logarithmic version of the adamk function:
int isNotZero(unsigned int n){
n |= n >> 16;
n |= n >> 8;
n |= n >> 4;
n |= n >> 2;
n |= n >> 1;
return n & 1;
};
And the fastest one, but in assembly:
xor eax, eax
sub eax, n // carry would be set if the number was not 0
xor eax, eax
adc eax, 0 // eax was 0, and if we had carry, it will became 1
Something similar to assembly version can be written in C, you just have to play with the sign bit and with some differences.
EDIT: here is the fastest version I can think of in C:
1) for negative numbers: if the sign bit is set, the number is not 0.
2) for positive: 0 - n will be negaive, and can be checked as in case 1. I don't see the - in the list of the legal operations, so we'll use ~n + 1 instead.
What we get:
int isNotZero(unsigned int n){ // unsigned is safer for bit operations
return ((n | (~n + 1)) >> 31) & 1;
}
int isNonZero(unsigned x) {
return ~( ~x & ( x + ~0 ) ) >> 31;
}
Assuming int is 32 bits (/* EDIT: this part no longer applies as I changed the parameter type to unsigned */ and that signed shifts behave exactly like unsigned ones).
Why make things complicated ?
int isNonZero(int x) {
return x;
}
It works because the C convention is that every non zero value means true, as isNonZero return an int that's legal.
Some people argued, the isNonZero() function should return 1 for input 3 as showed in the example.
If you are using C++ it's still as easy as before:
int isNonZero(int x) {
return (bool)x;
}
Now the function return 1 if you provide 3.
OK, it does not work with C that miss a proper boolean type.
Now, if you suppose ints are 32 bits and + is allowed:
int isNonZero(int x) {
return ((x|(x+0x7FFFFFFF))>>31)&1;
}
On some architectures you may even avoid the final &1, just by casting x to unsigned (which has a null runtime cost), but that is Undefined Behavior, hence implementation dependant (depends if the target architecture uses signed or logical shift right).
int isNonZero(int x) {
return ((unsigned)(x|(x+0x7FFFFFFF)))>>31;
}
int is_32bit_zero( int x ) {
return 1 ^ (unsigned) ( x + ~0 & ~x ) >> 31;
}
Subtract 1. (~0 generates minus one on a two's complement machine. This is an assumption.)
Select only flipped bit that flipped to one.
Most significant bit only flips as a result of subtracting one if x is zero.
Move most-significant bit to least-significant bit.
I count six operators. I could use 0xFFFFFFFF for five. The cast to unsigned doesn't count on a two's complement machine ;v) .
http://ideone.com/Omobw
Bitwise OR all bits in the number:
int isByteNonZero(int x) {
return ((x >> 7) & 1) |
((x >> 6) & 1) |
((x >> 5) & 1) |
((x >> 4) & 1) |
((x >> 3) & 1) |
((x >> 2) & 1) |
((x >> 1) & 1) |
((x >> 0) & 1);
}
int isNonZero(int x) {
return isByteNonZero( x >> 24 & 0xff ) |
isByteNonZero( x >> 16 & 0xff ) |
isByteNonZero( x >> 8 & 0xff ) |
isByteNonZero( x & 0xff );
}
basically you need to or the bits. For instance, if you know your number is 8 bits wide:
int isNonZero(uint8_t x)
{
int res = 0;
res |= (x >> 0) & 1;
res |= (x >> 1) & 1;
res |= (x >> 2) & 1;
res |= (x >> 3) & 1;
res |= (x >> 4) & 1;
res |= (x >> 5) & 1;
res |= (x >> 6) & 1;
res |= (x >> 7) & 1;
return res;
}
My solution is the following,
int isNonZero(int n)
{
return ~(n == 0) + 2;
}
My solution in C. No comparison operator. Doesn't work with 0x80000000.
#include <stdio.h>
int is_non_zero(int n) {
n &= 0x7FFFFFFF;
n *= 1;
return n;
}
int main(void) {
printf("%d\n", is_non_zero(0));
printf("%d\n", is_non_zero(1));
printf("%d\n", is_non_zero(-1));
return 0;
}
My solution,though not quite related to your question
int isSign(int x)
{
//return 1 if positive,0 if zero,-1 if negative
return (x > 0) - ((x & 0x80000000)==0x80000000)
}
if(x)
printf("non zero")
else
printf("zero")
The following function example should work for you.
bool isNonZero(int x)
{
return (x | 0);
}
This function will return x if it is non-zero, otherwise it will return 0.
int isNonZero(int x)
{
return (x);
}
int isNonZero(int x)
{
if ( x & 0xffffffff)
return 1;
else
return 0;
}
Let assume Int is 4 byte.
It will return 1 if value is non zero
if value is zero then it will return 0.
return ((val & 0xFFFFFFFF) == 0 ? 0:1);