I have access to an instrument that runs a C-style scripting language on it. It can declare and use variables or arrays of char, int and double but not float. It allows the operands of standard C logic and addition, subtraction, division and multiplication. It doesn't have useful functions such as sizeof() and doesn't have any of the bit shift operators <<, >>.
I am trying to get it to send a double value over two binary output ports. Each can be set High or low.
I was thinking that I should do this by bit-shift masking the double value using the bit-wise AND comparator. However I CAN'T do this because bit shift operators don't exist. I would then use one output port as a clock and the second as the synced data line.
For example using an input byte with value = 6 (0000 0110). The data would be output like below with X denoting the read value on the 'clock' down stroke:
*Clock, Input
* 0, 0
* 1, 0 X
* 0, 0
* 1, 1 X
* 0, 0
* 1, 1 X
* 0, 0
* 1, 0 X
* 0, 0
* 1, 0 X
* 0, 0
* 1, 0 X
* 0, 0
* 1, 0 X
* 0, 0
* 1, 0 X
* 0, 0
So I need a way of iterating through the double bit-by-bit (not sure how many bits the instrument uses for its double) and setting the output flag to its value but this can't be done with bit-shift because I don't have it.
Shifting a value is equivalente to multiply/divide by two (using integer math):
a / 2 equivalent to a >> 1
a * 2 equivalent to a << 1
You need to check that the scripting language do integer math (or use the floor() or int() or trunc() or wathever the language offers).
Be also careful with overflow, if the scripting language uses float instead of ints to represent numbers, you may expect strange behaviour with big numbers.
Another caveat on signedness. If you have to deal with negative numbers, shifting to left is more complicated.
Can you run a couple of tests to check the size of integer numbers? It will surely help you avoid problems.
A left shift 1 is equal to a multiply by 2, a right shift 1 is equal to (integer) division by 2. So, a left shift of 3 is equal to multiplication by 8 (because it is 23).
#include <stdio.h>
int main() {
int a = 17 << 4;
int b = 17 * 16;
if (a == b) {
printf("%i\n", b);
} else {
puts("false");
}
}
Output is
272
Assuming the measurements you are trying to retrieve are truly doubles: If you know the allowable range of the measurement, I would multiply them by a factor of 0xFFFFFFFF/MAX_RANGE factor to give you a value between 0 and int max.
Then you can do
long int value = double*FACTOR;
for (i=0;i<32;i++) {
long int nextval = value / 2;
char bit = value - (nextval * 2);
//send bit here
value = nextval;
}
This will be better than trying to work with the bitwise representation of floats without masks and shifting.
Bit shifts are just like multiplication or division, so the simplest solution to shift left/right N bits is just multiply/divide by 2N
const unsigned int SHIFT_BY[] = { 1U, 2U, 4U, 8U, 16U, 32U, 64U, 128U, 256U, 512U,
1024U, 2048U, 4096U, 8192U, 16384U, 32768U, 65536U, 131072U, 262144U, 524288U,
1048576U, 2097152U, 4194304U, 8388608U, 16777216U, 33554432U, 67108864U,
134217728U, 268435456U, 536870912U, 1073741824U, 2147483648U};
unsigned int lshift(unsigned int x, unsigned int numshift)
{
return x*SHIFT_BY[numshift];
}
unsigned int rshift(unsigned int x, unsigned int numshift)
{
return x/SHIFT_BY[numshift];
}
But that won't be efficient for small shift steps or on architectures without division/multiplication. In that case just add the number to itself since it's equivalent to multiplying it by 2 which may improve performance a bit
unsigned int lshift(unsigned int x, unsigned int numshift)
{
for (i = 0; i < numshift; i++)
x += x;
return x;
}
Right shift is a lot trickier to implement with only addition/subtraction. If you don't want to use the slow division then you can use a lookup table
unsigned int rshift1(unsigned int x)
{
const unsigned int RSHIFT1[] = { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7 };
assert(x < 16);
retrn RSHIFT1[x];
}
Above is just a simple 4-bit LUT to shift by 1. You can use a bigger LUT if you want/can. You can also implement shifting by more than 1 as a 2D array, or by shifting by 1 multiple times. This method can also be applied to left shift
Related
/*
* isPower2 - returns 1 if x is a power of 2, and 0 otherwise
* Examples: isPower2(5) = 0, isPower2(8) = 1, isPower2(0) = 0
* Note that no negative number is a power of 2.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 20
* Rating: 4
*/
int isPower2(int x) {
/*
* Variable a checks if x is power of 2, x and x - 1 won't have a 1
* in the same place if it's power of 2. Variable b checks if x is
* negative or zero. Use & to combine !a and b to complete the function.
*/
int a = x &(x+(~1+1));
int b = ((x+(~1+1))>> 31)+1;
return (!a)&b;
}
Hello every one, I am self-learning a course called CSE351 form Washton University and am finishing the lab1 about data manipulation in C. As you
can see about this question, I need to use the variable b to tell whether or not
the int x is zero.
And then I think that for zero or negative, if you minus one and then right shift 31 bits, adding one, you will get zero if the int is 0, and 1 if it is positive.
But however, my code didn't work, but I found a line of code works.
int b = ((!(x >> 31)) & (~(!x)));
I am really confused why my code don't work, can somebody tell me why?
Edit: Sorry, I didn't mention the environment of this lab is based on int with 32 bits and 2's complement for negative.
Several things to note (in your code):
first, (~1 + 1) is the same as ~0, and the same as -1 (in two's complement). Simpler, right?
x + (~0) is the same as x - 1. Simpler, right?
x & (x - 1) is 1 all the bits that don't change and are 1, when x is decremented. I think what you pretend here is to write x ^ (x - 1) that is, the set of bits that carry to the next on a decrement. This is the bits that change in a decrement. It happens that all bits change iff the number is a power of two. In case you want the bits that don't change, instead of using ^, just use & (bits that are 1 and don't change on a decrement which must be the empty set in case of a power of two ---we have to complement the result, as this boolean gives the opposite) This expression could be the result to get a power of two, if you consider the special case of 0 that is returned as a power of two. As with negatives, and 0, the logarithm does not exist, so we can simply say if (x <= 0) return 0; else return !(x & (x - 1)); (THIS CAN BE THE REQUESTED SOLUTION) or more compact return x <= 0 ? 0 : !(x&(x-1));.
~a as a consequence is _all the bits that do change OR are 0 when x is decremented. I'm lost completely here on what you pretend. I think you want to get if x <= 0 but that's so easy to write in C, instead of the complications you show.
So, your intentions (I guess) is to use the number of 1 bits that don't change on a decrement, because all bits do change for powers of two. Then, a possible implementation should be:
#include <stdio.h>
/*
* isPower2 - returns 1 if x is a power of 2, and 0 otherwise
* Examples: isPower2(5) = 0, isPower2(8) = 1, isPower2(0) = 0
* Note that no negative number is a power of 2. (and zero also, there's no logarithm of zero)
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 20
* Rating: 4
*/
int isPower2(int x) {
return x <= 0
? 0
: !(x&(x-1));
}
/* please, always post complete and verifiable code, with header files,
* and the like, so we can test it without having to first modify it.
*/
int main()
{
for (;;) {
int a;
scanf("%d", &a);
printf("isPower2(a=%d) => %d\n", a, isPower2(a));
}
}
NOTE
Anyway, I don't have a clear idea of the result you want to get, as you entitle the question as Problems about check a integer is zero or negative... and then you show partial code (see How to create a Minimal, Complete, and Verifiable example) about how to detect if some given integer is a power of two but then, you show then some strange code to check if a number is negative. It suffices to do:
if (x <= 0) do_bla_bla();
and this doesn't produce undefined behaviour with 31 bit right shifts.
NOTE
if you need to use only the operators in the list, just change <= by the following:
#define SIGNBIT (~(~0>>1)) /* ALL ONES, SHIFTED ONE BIT RIGHT AND COMPLEMENTED */
return
x & SIGNBIT /* sign bit on, negative number */
|| !x /* OR x == 0 */
? 0
: !(x&(x-1));
The final code is:
#include <stdio.h>
/*
* isPower2 - returns 1 if x is a power of 2, and 0 otherwise
* Examples: isPower2(5) = 0, isPower2(8) = 1, isPower2(0) = 0
* Note that no negative number is a power of 2. (and zero also, there's no logarithm of zero)
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 20
* Rating: 4
*/
#define SIGNBIT (~(~0>>1))
int isPower2(int x) {
return x & SIGNBIT || !x ? 0 : !(x&(x-1));
/* if anybody tells you are using ? and || operators, just write:
* if (x & SIGNBIT) return 0;
* if (!x) return 0;
* return !(x&(x-1));
*/
}
/* please, always post complete and verifiable code, with header files,
* and the like, so we can test it without having to first modify it.
*/
int main()
{
for (;;) {
int a;
scanf("%d", &a);
printf("isPower2(a=%d) => %d\n", a, isPower2(a));
}
}
I dont understand why the interger Value "hash" is getting lower in/after the 3 loop.
I would guess this happen because the uint limitation is 2,147,483,647.
BUT... when i try to go step by step the value is equal to 2146134658?.
I´m not that good in math but it should be lower than the limitation.
#define FNV_PRIME_32 16777619
#define FNV_OFFSET_32 2166136261U
unsigned int hash_function(const char *string, unsigned int size)
{
unsigned int str_len = strlen(string);
if (str_len == 0) exit(0);
unsigned int hash = FNV_OFFSET_32;
for (unsigned int i = 0; i < str_len; i++)
{
hash = hash ^ string[i];
// Multiply by prime number found to work well
hash = hash * FNV_PRIME_32;
if (hash > 765010506)
printf("YO!\n");
else
printf("NOO!\n");
}
return hash % size;
}
If you are wondering this if statement is only for me.
if (hash > 765010506)
printf("YO!\n");
else
printf("NOO!\n");
765010506 is the value for hash after the next run through the loop.
I dont understand why the interger Value "hash" is getting lower in/after the 3 loop.
All unsigned integer arithmetic in C is modular arithmetic. For unsigned int, it is modulo UINT_MAX + 1; for unsigned long, modulo ULONG_MAX + 1, and so on.
(a modulo m means the remainder of a divided by m; in C, a % m if both a and m are unsigned integer types.)
On many current architectures, unsigned int is a 32-bit unsigned integer type, with UINT_MAX == 4294967295.
Let's look at what this means in practice, for multiplication (by 65520, which happens to be an interesting value; 216 - 16):
unsigned int x = 1;
int i;
for (i = 0; i < 10; i++) {
printf("%u\n", x);
x = x * 65520;
}
The output is
1
65520
4292870400
50327552
3221291008
4293918720
16777216
4026531840
0
0
What? How? How come the result ends up zero? That cannot happen!
Sure it can. In fact, you can show mathematically that it happens eventually whenever the multiplier is even, and the modulo is with respect to a power of two (232, here).
Your particular multiplier is odd, however; so, it does not suffer from the above. However, it still wraps around due to the modulo operation. If we retry the same with your multiplier, 16777619, and a bit longer sequence,
unsigned int x = 1;
int i;
for (i = 0; i < 20; i++) {
printf("%u\n", x);
x = x * 16777619;
}
we get
1
16777619
637696617
1055306571
1345077009
1185368003
4233492473
878009595
1566662433
558416115
1485291145
3870355883
3549196337
924097827
3631439385
3600621915
878412353
2903379027
3223152297
390634507
In fact, it turns out that this sequence is 1,073,741,824 iterations long (before it repeats itself), and will never yield 0, 2, 4, 5, 6, 7, 8, 10, 12, 13, 14, or 15, for example -- that is, if it starts from 1. It even takes 380 iterations to get a result smaller than 16,777,619 (16,689,137).
For a hash function, that is okay. Each new nonzero input changes the state, so the sequence is not "locked". But, there is no reason to expect the hash value increases monotonically as the length of the hashed data increases; it is much better to assume it is "roughly random" instead: not really random, as it depends on the input only, but also not obviously regular-looking.
I would guess this happen because the uint limitation is 2,147,483,647.
The maximum value of a 32-bit unsigned integer is roughly 4 billion (232 - 1 = 4,294,967,295). The number you're thinking of is the maximum value of a signed integer (231 - 1).
2,146,134,658 is slightly less than 231 (so it could fit in even an unsigned 32-bit integer), but it's still very close to the limit. Multiplying it by FNV_PRIME_32 -- which is roughly 224 -- will give a result of roughly 255, which will cause overflow.
int a = 12;
for eg: binary of 12 is 1100 so answer should be 3 as 3rd bit from right is set.
I want the position of the last most set bit of a. Can anyone tell me how can I do so.
NOTE : I want position only, here I don't want to set or reset the bit. So it is not duplicate of any question on stackoverflow.
This answer Unset the rightmost set bit tells both how to get and unset rightmost set bit for an unsigned integer or signed integer represented as two's complement.
get rightmost set bit,
x & -x
// or
x & (~x + 1)
unset rightmost set bit,
x &= x - 1
// or
x -= x & -x // rhs is rightmost set bit
why it works
x: leading bits 1 all 0
~x: reversed leading bits 0 all 1
~x + 1 or -x: reversed leading bits 1 all 0
x & -x: all 0 1 all 0
eg, let x = 112, and choose 8-bit for simplicity, though the idea is same for all size of integer.
// example for get rightmost set bit
x: 01110000
~x: 10001111
-x or ~x + 1: 10010000
x & -x: 00010000
// example for unset rightmost set bit
x: 01110000
x-1: 01101111
x & (x-1): 01100000
Finding the (0-based) index of the least significant set bit is equivalent to counting how many trailing zeros a given integer has. Depending on your compiler there are builtin functions for this, for example gcc and clang support __builtin_ctz.
For MSVC you would need to implement your own version, this answer to a different question shows a solution making use of MSVC intrinsics.
Given that you are looking for the 1-based index, you simply need to add 1 to ctz's result in order to achieve what you want.
int a = 12;
int least_bit = __builtin_ctz(a) + 1; // least_bit = 3
Note that this operation is undefined if a == 0. Furthermore there exist __builtin_ctzl and __builtin_ctzll which you should use if you are working with long and long long instead of int.
One can use the property of 2s-complement here.
Fastest way to find 2s-complement of a number is to get the rightmost set bit and flip everything to the left of it.
For example: consider a 4 bit system
/* Number in binary */
4 = 0100
/* 2s complement of 4 */
complement = 1100
/* which nothing but */
complement == -4
/* Result */
4 & (-4) = 0100
Notice that there is only one set bit and its at rightmost set bit of 4.
Similarly we can generalise this for n.
n&(-n) will contain only one set bit which is actually at the rightmost set bit position of n.
Since there is only one set bit in n&(-n), it is a power of 2.
So finally we can get the bit position by:
log2(n&(-n))+1
The leftmost bit of n can be obtained using the formulae:
n & ~(n-1)
This works because when you calculate (n-1) .. you are actually making all the zeros till the rightmost bit to 1, and the rightmost bit to 0.
Then you take a NOT of it .. which leaves you with the following:
x= ~(bits from the original number) + (rightmost 1 bit) + trailing zeros
Now, if you do (n & x), you get what you need, as the only bit that is 1 in both n and x is the rightmost bit.
Phewwwww .. :sweat_smile:
http://www.catonmat.net/blog/low-level-bit-hacks-you-absolutely-must-know/
helped me understand this.
There is a neat trick in Knuth 7.1.3 where you multiply by a "magic" number (found by a brute-force search) that maps the first few bits of the number to a unique value for each position of the rightmost bit, and then you can use a small lookup table. Here is an implementation of that trick for 32-bit values, adapted from the nlopt library (MIT/expat licensed).
/* Return position (0, 1, ...) of rightmost (least-significant) one bit in n.
*
* This code uses a 32-bit version of algorithm to find the rightmost
* one bit in Knuth, _The Art of Computer Programming_, volume 4A
* (draft fascicle), section 7.1.3, "Bitwise tricks and
* techniques."
*
* Assumes n has a 1 bit, i.e. n != 0
*
*/
static unsigned rightone32(uint32_t n)
{
const uint32_t a = 0x05f66a47; /* magic number, found by brute force */
static const unsigned decode[32] = { 0, 1, 2, 26, 23, 3, 15, 27, 24, 21, 19, 4, 12, 16, 28, 6, 31, 25, 22, 14, 20, 18, 11, 5, 30, 13, 17, 10, 29, 9, 8, 7 };
n = a * (n & (-n));
return decode[n >> 27];
}
Try this
int set_bit = n ^ (n&(n-1));
Explanation:
As noted in this answer, n&(n-1) unsets the last set bit.
So, if we unset the last set bit and xor it with the number; by the nature of the xor operation, the last set bit will become 1 and the rest of the bits will return 0
1- Subtract 1 form number: (a-1)
2- Take it's negation : ~(a-1)
3- Take 'AND' operation with original number:
int last_set_bit = a & ~(a-1)
The reason behind subtraction is, when you take negation it set its last bit 1, so when take 'AND' it gives last set bit.
Check if a & 1 is 0. If so, shift right by one until it's not zero. The number of times you shift is how many bits from the right is the rightmost bit that is set.
You can find the position of rightmost set bit by doing bitwise xor of n and (n&(n-1) )
int pos = n ^ (n&(n-1));
I inherited this one, with a note that it came from HAKMEM (try it out here). It works on both signed and unsigned integers, logical or arithmetic right shift. It's also pretty efficient.
#include <stdio.h>
int rightmost1(int n) {
int pos, temp;
for (pos = 0, temp = ~n & (n - 1); temp > 0; temp >>= 1, ++pos);
return pos;
}
int main()
{
int pos = rightmost1(16);
printf("%d", pos);
}
You must check all 32 bits starting at index 0 and working your way to the left. If you can bitwise-and your a with a one bit at that position and get a non-zero value back, it means the bit is set.
#include <limits.h>
int last_set_pos(int a) {
for (int i = 0; i < sizeof a * CHAR_BIT; ++i) {
if (a & (0x1 << i)) return i;
}
return -1; // a == 0
}
On typical systems int will be 32 bits, but doing sizeof a * CHAR_BIT will get you the right number of bits in a even if it's a different size
Accourding to dbush's solution, Try this:
int rightMostSet(int a){
if (!a) return -1; //means there isn't any 1-bit
int i=0;
while(a&1==0){
i++;
a>>1;
}
return i;
}
return log2(((num-1)^num)+1);
explanation with example: 12 - 1100
num-1 = 11 = 1011
num^ (num-1) = 12^11 = 7 (111)
num^ (num-1))+1 = 8 (1000)
log2(1000) = 3 (answer).
x & ~(x-1) isolates the lowest bit that is one.
int main(int argc, char **argv)
{
int setbit;
unsigned long d;
unsigned long n1;
unsigned long n = 0xFFF7;
double nlog2 = log(2);
while(n)
{
n1 = (unsigned long)n & (unsigned long)(n -1);
d = n - n1;
n = n1;
setbit = log(d) / nlog2;
printf("Set bit: %d\n", setbit);
}
return 0;
}
And the result is as below.
Set bit: 0
Set bit: 1
Set bit: 2
Set bit: 4
Set bit: 5
Set bit: 6
Set bit: 7
Set bit: 8
Set bit: 9
Set bit: 10
Set bit: 11
Set bit: 12
Set bit: 13
Set bit: 14
Set bit: 15
Let x be your integer input.
Bitwise AND by 1.
If it's even ie 0, 0&1 returns you 0.
If it's odd ie 1, 1&1 returns you 1.
if ( (x & 1) == 0) )
{
std::cout << "The rightmost bit is 0 ie even \n";
}
else
{
std::cout<< "The rightmost bit is 1 ie odd \n";
}```
Alright, so number systems is just working with logarithms and exponents. So I'll dive down into an approach that really makes sense to me.
I would prefer you read this because I write there about how I interpret logarithms as.
When you perform the x & -x operation, it gives you the value which has the right most bit as 1 (for example, it can be 0001000 or 0000010. Now according to how I interpret logarithms as, this value of the right most set bit, is the final value after I grow at the rate of 2. Now we are interested in finding the number of digits in this answer because whatever that is, if you subtract 1 from it, that is precisely the bit-count of set bit (bit count begins with 0 here and the digit count begins with 1, so yeah). But the number of digits is precisely the time you expanded for + 1 (in accordance with my logic) or just the formula I mentioned in the previous link. But now, as we don't really need the digits, but need the bit count, and we also don't have to worry about values of bits which potentially can be real (if the number is 65) because the number is always some multiple of 2 (except 1). So if you just take the logarithm of the value x & -x, we get the bit count! I did see an answer before that mentioned this, but diving down to why it really works was something I felt like writing down.
P.S: You could also count the number of digits and then subtract 1 from it to get the bit-count.
i wrote the following test code to check fixed point arithmetic and bit shifting.
void main(){
float x = 2;
float y = 3;
float z = 1;
unsigned int * px = (unsigned int *) (& x);
unsigned int * py = (unsigned int *) (& y);
unsigned int * pz = (unsigned int *) (& z);
*px <<= 1;
*py <<= 1;
*pz <<= 1;
*pz =*px + *py;
*px >>= 1;
*py >>= 1;
*pz >>= 1;
printf("%f %f %f\n",x,y,z);
}
The result is
2.000000 3.000000 0.000000
Why is the last number 0? I was expecting to see a 5.000000
I want to use some kind of fixed point arithmetic to bypass the use of floating point numbers on an image processing application. Which is the best/easiest/most efficient way to turn my floating point arrays into integers? Is the above "tricking the compiler" a robust workaround? Any suggestions?
If you want to use fixed point, dont use type 'float' or 'double' because them has internal structure. Floats and Doubles have specific bit for sign; some bits for exponent, some for mantissa (take a look on color image here); so they inherently are floating point.
You should either program fixed point by hand storing data in integer type, or use some fixed-point library (or language extension).
There is a description of Floating point extensions implemented in GCC: http://gcc.gnu.org/onlinedocs/gcc/Fixed_002dPoint.html
There is some MACRO-based manual implementation of fixed-point for C: http://www.eetimes.com/discussion/other/4024639/Fixed-point-math-in-C
What you are doing are cruelties to the numbers.
First, you assign values to float variables. How they are stored is system dependant, but normally, IEEE 754 format is used. So your variables internally look like
x = 2.0 = 1 * 2^1 : sign = 0, mantissa = 1, exponent = 1 -> 0 10000000 00000000000000000000000 = 0x40000000
y = 3.0 = 1.5 * 2^1 : sign = 0, mantissa = 1.5, exponent = 1 -> 0 10000000 10000000000000000000000 = 0x40400000
z = 1.0 = 1 * 2^0 : sign = 0, mantissa = 1, exponent = 0 -> 0 01111111 00000000000000000000000 = 0x3F800000
If you do some bit shiftng operations on these numbers, you mix up the borders between sign, exponent and mantissa and so anything can, may and will happen.
In your case:
your 2.0 becomes 0x80000000, resulting in -0.0,
your 3.0 becomes 0x80800000, resulting in -1.1754943508222875e-38,
your 1.0 becomes 0x7F000000, resulting in 1.7014118346046923e+38.
The latter you lose by adding -0.0 and -1.1754943508222875e-38, which becomes the latter, namely 0x80800000, which should be, after >>ing it by 1, 3.0 again. I don't know why it isn't, probably because I made a mistake here.
What stays is that you cannot do bit-shifting on floats an expect a reliable result.
I would consider converting them to integer or other fixed-point on the ARM and sending them over the line as they are.
It's probable that your compiler uses IEEE 754 format for floats, which in bit terms, looks like this:
SEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFF
^ bit 31 ^ bit 0
S is the sign bit s = 1 implies the number is negative.
E bits are the exponent. There are 8 exponent bits giving a range of 0 - 255 but the exponent is biased - you need to subtract 127 to get the true exponent.
F bits are the fraction part, however, you need to imagine an invisible 1 on the front so the fraction is always 1.something and all you see are the binary fraction digits.
The number 2 is 1 x 21 = 1 x 2128 - 127 so is encoded as
01000000000000000000000000000000
So if you use a bit shift to shift it right you get
10000000000000000000000000000000
which by convention is -0 in IEEE754, so rather than multiplying your number by 2 your shift has made it zero.
The number 3 is [1 + 0.5] x 2128 - 127
which is represented as
01000000010000000000000000000000
Shifting that left gives you
10000000100000000000000000000000
which is -1 x 2-126 or some very small number.
You can do the same for z, but you probably get the idea that shifting just screws up floating point numbers.
Fixed point doesn't work that way. What you want to do is something like this:
void main(){
// initing 8bit fixed point numbers
unsigned int x = 2 << 8;
unsigned int y = 3 << 8;
unsigned int z = 1 << 8;
// adding two numbers
unsigned int a = x + y;
// multiplying two numbers with fixed point adjustment
unsigned int b = (x * y) >> 8;
// use numbers
printf("%d %d\n", a >> 8, b >> 8);
}
This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
Best algorithm to count the number of set bits in a 32-bit integer?
Given a 32-bit integer N,Devise an algorithm to find the number of zeros in the binary bit representation of N.
The simplest algorithm I can think of is to check the binary representation for Zeros,in C something like this:
int num_of_zero(int num)
{
if(0 == num) return 1; /*For the input 0 it should output 1 */
int Count = 0;
while(num>0){
if(0 == (num&1)) Count++;
num >>= 1;
}
return Count;
}
I was wandering if there is some algorithm to compute at constant time.
For input 0 it should return 1 not 32.
For 5 the output should be 1.As binary representation is 101.
For 7 the output should be 0.
Precisely,I am looking for a better algorithm to compute number of (non-leading) zeros in the binary interpretation of an 32 bit integer.Hope the problem is clear now.
Edit: As pointed Alex Martelli,delroth I am modifying my code to made it more readable & using iteration this time.
The simple way to do this is to iterate over each bit of the binary representation of the number, test the value of each bit, and count up how many of them are zero. A loop would be much clearer than recursion for this.
There are many more optimized methods for doing this, though. You can find some of the better ones in answers to this question, "Best algorithm to count the number of set bits in a 32-bit integer" (obviously, the number of zero bits is the number of set bits subtracted from the total number of bits).
There's a great resource online called Bit Twiddling Hacks that contains all sorts of great little C tricks. You may be particularly interested in the Counting bits set section.
Quick and dumb way -- there are more exotic implementations in the duplicate question, but I have used something similar to this without much ill effect in the past.
We use a table of nibbles here to reduce the number of times the loop is run -- if you're doing a boatload of these computations, it might be more efficient to build a much bigger array, say, at the byte level, cutting the loop runs in half.
/* How many bits are set in every possible nibble. */
static size_t BIT_TABLE[] = {
0, 1, 1, 2, /* 0, 1, 2, 3 */
1, 2, 2, 3, /* 4, 5, 6, 7 */
1, 2, 2, 3, /* 8, 9, A, B */
2, 3, 3, 4 /* C, D, E, F */
};
size_t num_of_bits(int num) {
/* Little reworking could probably shrink the stack space in use here. */
size_t ret = 0, i;
register int work = num;
/* Iterate every nibble, rotating the integer in place. */
for(i = 0; i < (sizeof(num) * 2); i++) {
/* Pointer math to get a member of the static array. */
ret += *(BIT_TABLE + (work & 0xF));
work >>= 4;
}
return ret;
}
Recursion is definitely overkill -- and besides, your code's quite buggy (it will not count any of the leading zeros of num!!!). A simple iteration, such as:
int num_of_zero(int num) {
unsigned int unum = (unsigned int)num;
int count;
int i;
for(i = 0; i < 32; ++i) {
if(!(unum & 1)) ++count;
unum >>= 1;
}
return count;
}
is correct and faster (can be coded more concisely, but I think this is the clearest expression).
If you have to do this computation many times, consider precomputing an array of (say) 256 "counts of zeros" (each value giving the count for its index, 0 to 255 included, as an 8-bit number). Then you can loop just 4 times (masking and shifting 8 bits at a time), and easily unroll the loop -- if your compiler's not smart enough to do it on your behalf;-).
I'm guessing that this is a homework question. No problem! Here's the fastest possible solution (after a long startup cost):
Make an array of byte that is 232 long. Precompute the value of the number of zeros in the binary representation for each possible int value to fill in that array. From then on, you'll have an array that will give you the number of zeros per value.
Yes, that solution is silly -- it's a lot of work for little gain -- but combine it with one other idea:
What happens if you just precompute the values that are 8 bits long? Would you be able to write code that, though not quite as fast, would still return the number of 0-bits in a int?
What happens if you just precompute the values that are 4 bits long? 2 bits long? 1 bit long?
I hope this gives you ideas for a better algorthm...
It is not really an answer to your main question, but you should rewrite your recursive function like this :
int num_of_zero(int num)
{
int left_part_zeros;
if (num == 0)
return 0;
left_part_zeros = num_of_zero(num >> 1);
if ((num & 1) == 0)
return left_part_zeros + 1;
else
return left_part_zeros;
}
Your implementation have a lot of problems, beside being completely unreadable.
The easiest way I found was to base it on something that counts the ones then simply subtract that from 32 (assuming that you're sure the int size is 32 bits).
int numberOfOnes (int num) {
int count = 0;
unsigned int u = (unsigned int)num;
while (u != 0) {
if ((u&1) == 1)
count++;
u >>= 1;
}
return count;
}
int numberOfZeros (int num) {
return 32 - numberOfOnes (num);
}
This actually gives you both variants (ones and zeros) - there are faster ways to do it but I wouldn't consider them unless and until you know there's a performance problem. I tend to code for readability first.
You may also want to at least test the possibility that a table lookup could be faster (the prime directive of optimisation is measure, don't guess!
One possibility there could be replacing the numberOfOnes function with something that operates a nybble at a time:
int numberOfOnes (int num) {
static const count[] = {
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
};
int retval = 0;
unsigned int u = (unsigned int)num;
while (u != 0) {
retval += count[u & 0x0f]
u >>= 4;
}
return retval;
}