I can only use these symbols:
! ~ & ^ | + << >>
Here is the table I need to achieve:
input | output
--------------
0 | 0
1 | 8
2 | 16
3 | 24
With the output I am going to left shift a 32 bit int over.
Ex.
int main()
{
int myInt = 0xFFFFFFFF;
myInt = (x << (myFunction(2)));
//OUTPUT = 0xFFFF0000
}
int myFunction(int input)
{
// Do some magic conversions here
}
any ideas????
Well, if you want a function with f(0) = 0, f(1) = 8, f(3) = 24 and so on then you'll have to implement f(x) = x * 8. Since 8 is a perfect power of two the multiplication can be replaced by shifting. Thus:
int myFunction(int input)
{
return input << 3;
}
That's all.
Related
Given two sets of numbers encoded with bitwise operations (using 6 bits for number):
a = {12,20,21,24,31}
b = {13,18,24,28,35}
Intersection -> a ∩ b = {24}
unsigned int a = 0;
a |= (12 | 20 << 6 | 21 << 12 | 24 << 18 | 31 << 24);
unsigned int b = 0;
b |= (13 | 18 << 6 | 24 << 12 | 28 << 18 | 35 << 24);
What is the fastest way to find out, if there is at least one number in common between the sets?
This is just an example, but you can have common numbers in any position.
#include <stdint.h>
#include <limits.h>
typedef unsigned int SetType;
#define FieldWidth 6 // Number of bits per field.
#define NumberOfFields (sizeof(SetType) * CHAR_BIT / FieldWidth)
// Return non-zero iff some element is in both a and b.
int IsIntersectionNonEmpty(SetType a, SetType b)
{
// Create masks with a bit set for each element an input set.
uint64_t A = 0, B = 0;
for (int i = 0; i < NumberOfFields; ++i)
{
A |= UINT64_C(1) << (a >> i*6 & 0x3f);
B |= UINT64_C(1) << (b >> i*6 & 0x3f);
/* ">> i*6" moves field i to the low bits.
"& 0x3f" isolates that six-bit field.
"UINT64_C(1) << …" generates a 1 bit in that position.
*/
}
/* Bitwise AND A and B to see if they have a bit in common, then
convert that to 1 or 0.
*/
return !! (A & B);
}
Maybe not the absolute fastest, but I'd XOR a with b, and see if the result has any six-bit all-zeros pattern in any of your 5 positions. Then shift one of them by 6 bits and repeat up to 4 more times if needed.
Here's a somewhat faster version of my solution above; instead of shifting left and right, just rotate:
int leftRotate(unsigned int n, unsigned int d)
{
return (n << d)|(n >> (32 - d));
}
// Return non-zero iff some element is in both a and b.
int IsIntersectionNonEmpty(unsigned int a, unsigned int b)
{
for (int i = 0; i < 5; i++) {
unsigned int matches = leftRotate(a, i*6) ^ b;
for (int j = 0; j < 5; j++) {
unsigned int testval = 0x3f << j*6;
if (matches & testval == testval)
return 1; // success
}
}
return 0;
}
5 instructions in the outer loop, 3 in the inner * 5, so 20 total, times 5 loops, around 100 instructions total -- but as soon as it finds a match it returns. So if there are frequent matches it'll likely be faster than the #eric-postpischil version, but with no matches it'll be slower. On the other hand, his solution is likely auto-vectorizable with a smart compiler.
Well, thanks to everyone, but thank to the guy that posted the EL code, I do not know why he withdrew it.
Here we go, as fast as light:
#define EL(x) (UINT64_C(1) << (x))
unsigned int a = 0;
a |= (12 | 20 << 6 | 21 << 12 | 24 << 18 | 31 << 24);
unsigned int b = 0;
b |= (13 | 18 << 6 | 24 << 12 | 28 << 18 | 35 << 24);
unsigned int aa = EL(a & 0x00000003F) | EL((a & 0x000000FC0) >> 6) | EL((a & 0x3F000) >> 12) | EL((a & 0xFC0000) >> 18) | EL((a & 0x3F000000) >> 24);
unsigned int bb = EL(b & 0x00000003F) | EL((b & 0x000000FC0) >> 6) | EL((b & 0x3F000) >> 12) | EL((b & 0xFC0000) >> 18) | EL((b & 0x3F000000) >> 24);
anb = !! (aa & bb); // intersection
I am trying to "build a new number by reversing its nibbles".
This is the exercise:
Write a function that given an unsigned n
a) returns the value with the nibbles placed in reverse order
I was thinking that all the 8 nibbles from the 32 bit unsigned should be placed in reverse order. So , as an example for the number 24, which is 00000000000000000000000000011000.
=> The reversed value should be: 10000001000000000000000000000000.
#include <stdio.h>
unsigned getNibble(unsigned n,unsigned p){
unsigned mask = 0xFu;
unsigned nibble = 0;
nibble = (n&(mask<<p))>>p;
return nibble;
}
unsigned swapNibbles(unsigned n){
unsigned new = 0;
unsigned nibble;
for(unsigned i=0;i<(sizeof(n)*8);i=i+4){
nibble = getNibble(n,i);
new = (new<<i) + nibble;
}
return new;
}
int main(void) {
printf("0x%x",swapNibbles(24));
return 0;
}
I tried to debug it , and it went well until one point.
At one of the right shifts , it transformed my "new" variable into 0.
This statement
new = (new << i) + nibble;
is wrong. There should be
new = (new << 4) + nibble;
An approach that does work in parallel:
uint32_t n = ...;
// Swap the nibbles of each byte.
n = (n & 0x0F0F0F0F ) << 4
| (n & 0xF0F0F0F0 ) >> 4;
// Swap the bytes of each byte pair.
n = ( n & 0x00FF00FF ) << 8
| ( n & 0xFF00FF00 ) >> 8;
// Swap the byte pairs.
n = ( n & 0x0000FFFF ) << 16
| ( n & 0xFFFF0000 ) >> 16;
Doing the work in parallel greatly reduces the number of operations.
OP's This
Approach Approach
-------- --------- ---------
Shifts 24 / 48 6 / 8 32 bits / 64 bits
Ands 8 / 16 6 / 8
Ors* 8 / 16 3 / 4
Assigns 8 / 16 3 / 4
Adds 8 / 16 0 / 0
Compares 8 / 16 0 / 0
-------- --------- ---------
Total 64 / 128 18 / 24
-------- --------- ---------
Scale O(N) O(log(N))
* Addition was used as "or" in the OP's solution.
int main (void)
{
uint32_t x = 0xDEADBEEF;
printf("original 4 bytes %X\n", x);
uint32_t y = 0;
for(uint8_t i = 0 ; i < 32 ; i += 4)
{
y <<= 4;
y |= x>>i & 0xF;
}
printf("reverse order nibbles %X\n", y);
return 0;
}
This could be made generic function for accepting all 8,16,32 bits numbers. But for now this resolves the bug you are facing in your code.
But I would point out ikegami's code is much better than this approach.
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
I have a byte array represented as
char * bytes = getbytes(object); //some api function
I want to check whether the bit at some position x is set.
I've been trying this
int mask = 1 << x % 8;
y= bytes[x>>3] & mask;
However y returns as all zeros? What am I doing incorrectly and is there an easier way to check if a bit is set?
EDIT:
I did run this as well. It didn't return with the expected result either.
int k = x >> 3;
int mask = x % 8;
unsigned char byte = bytes[k];
return (byte & mask);
it failed an assert true ctest I ran. Byte and Mask at this time where "0002" and 2 respectively when printed from gdb.
edit 2: This is how I set the bits in the first place. I'm just trying to write a test to verify they are set.
unsigned long x = somehash(void* a);
unsigned int mask = 1 << (x % 8);
unsigned int location = x >> 3;
char* filter = getData(ref);
filter[location] |= mask;
This would be one (crude perhaps) way from the top of my head:
#include "stdio.h"
#include "stdlib.h"
// this function *changes* the byte array
int getBit(char *b, int bit)
{
int bitToCheck = bit % 8;
b = b + (bitToCheck ? (bit / 8) : (bit / 8 - 1));
if (bitToCheck)
*b = (*b) >> (8 - bitToCheck);
return (*b) & 1;
}
int main(void)
{
char *bytes = calloc(2, 1);
*(bytes + 1)= 5; // writing to the appropiate bits
printf("%d\n", getBit(bytes, 16)); // checking the 16th bit from the left
return 0;
}
Assumptions:
A byte is represented as:
----------------------------------------
| 2^7 | 2^6 | 2^5 | 2^4 | 2^3 |... |
----------------------------------------
The left most bit is considered bit number 1 and the right most bit is considered the max. numbered bit (16th bit in a 2 byte object).
It's OK to overwrite the actual byte object (if this is not wanted, use memcpy).
Given a number (int a = 0XABCDE98) I am trying to set the D bit to 6.
ie after the Bit manipulation the number should be (0XABC6E98).
I have written a small C program to do the bit manipulation, but somehow I am not able to see the correct bit change.
Please help me in finding what might be missing in the program.
#include<stdio.h>
int main()
{
int n = 0xABCDE98;
n |= (n & 0X0000) | 0x6000;
printf("%x\n", n);
return 0;
}
o/p - abcfe98
In your code
n |= (n & 0X0000) | 0x6000;
is wrong beacuse of is equal to
0xABCDE98 & 0x0000 = 0 and 0x0000 | 0x6000 = 0x6000 and 0xABCDE98 | 0x6000 = 0xABCFDE98
Instead you must write
n = (n & 0XFFF0FFF) | 0x6000;
Change:
n |= (n & 0X0000) | 0x6000;
to:
n &= ~0xd000;
n |= 0x6000;
or just:
n = (n & ~0xd000) | 0x6000;
if you prefer.
Test:
#include <stdio.h>
int main()
{
int n = 0xABCDE98;
n &= ~0x000d000; // clear nybble
n |= 0x0006000; // set nybble to 6
printf("%#x\n", n);
return 0;
}
Compile and run:
$ gcc -Wall temp.c && ./a.out
0xabc6e98
LIVE CODE
Try This:
#include<stdio.h>
int main()
{
int n = 0xABCDE98;
n = n ^ 0x000B000; //Ex-OR 'n' with 0x000B000
printf("%x\n", n);
return 0;
}
o/p - abc6e98
Lets have a look at what your program is doing:
(n & 0x0000)
Truth Table AND:
Anything & 0 = 0, so the result of this is simply 0x0000
Truth Table OR:
0 | Anything = Anything
so now (0x0000) | 0x6000 = 0x6000
Effectively the line:
n |= (n & 0X0000) | 0x6000;
simplifies to:
n |= 0x6000
The 4th last digit of n = D
Hex math: D | 6 = F
hence your result 0xABCFE98
Solution?
You need to try and 0 only the D digit first then OR with 0x6000 to set it to 6. There are many ways of doing this as suggested by other posters.
n = (n - 0xD000) | 0x6000 would also do the trick.
Try the following
#include <stdio.h>
int main( void )
{
int x = 0XABCDE98;
x = ( ~0xF000 & x ) | 0x6000;
printf( "%#X\n", x );
return 0;
}
The output is
0XABC6E98
n & 0x0000 "delete" the four last digits, so replace it with n & 0xFFF0FFF. That will keep all the digits except the fourth one (the 0).