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).
Related
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 wan't to set the last n bits of any given number to 1. I have a number (which is variable in it's lenght) and a variable n.
Example:
12 (dec) set last 2 bits
Output: 15
Now the basic operation should be something like:
return 0b11 | 12;
But how can I make 0b11 variable in length?
Thank you!
Try this:
int SetLastBits(int value,int numOfBits)
{
return value | ((1<<numOfBits)-1);
}
You can set the last n bits of a number to 1 in the following manner:
int num = 5; // number of bits to set to 1
int val = <some_value>;
val |= (1 << num) - 1;
You can do it like this:
uint32_t set_last_n_bits(uint32_t x, uint32_t bits)
{
return x | ((1U << bits) - 1U);
}
This is also a relatively rare case where a macro might be justifiable, on the grounds that it would work with different integer types.
As all others have showed the same approach I will show one more approach
int value;
//...
value |= ~( ~0u << n );
Here is a demonstrative program
#include <stdio.h>
int set_bits( int x, size_t n )
{
return x | ~( ~0u << n );
}
int main(void)
{
int x = 12;
printf( "%d\t%d\n", x, set_bits( x, 2 ) );
return 0;
}
The output is
12 15
I need to make an assignment where I switch the values of a certain int. For example: 0xaabbccdd should be turned in to 0xddccbbaa.
I've already extraced all of the bytes from the given number and their values are correct.
unsigned int input;
scanf("%i", &input);
unsigned int first_byte = (input >> (8*0)) & 0xff;
unsigned int second_byte = (input >> (8*1)) & 0xff;
unsigned int third_byte = (input >> (8*2)) & 0xff;
unsigned int fourth_byte = (input >> (8*3)) & 0xff;
Now I'm trying to set an empty int variable (aka 00000000 00000000 00000000 00000000) to those byte values, but turned around. So how can I say that the first byte of the empty variable is the fourth byte of the given input? I've been trying different combinations of bitwise operations, but I can't seem to wrap my head around it. I'm pretty sure I should be able to do something like:
answer *first byte* | fourth_byte;
I would appreciate any help, becau'se I've been stuck and searching for an answer for a couple of hours now.
Based on your code :
#include <stdio.h>
int main(void)
{
unsigned int input = 0xaabbccdd;
unsigned int first_byte = (input >> (8*0)) & 0xff;
unsigned int second_byte = (input >> (8*1)) & 0xff;
unsigned int third_byte = (input >> (8*2)) & 0xff;
unsigned int fourth_byte = (input >> (8*3)) & 0xff;
printf(" 1st : %x\n 2nd : %x\n 3rd : %x\n 4th : %x\n",
first_byte,
second_byte,
third_byte,
fourth_byte);
unsigned int combo = first_byte<<8 | second_byte;
combo = combo << 8 | third_byte;
combo = combo << 8 | fourth_byte;
printf(" combo : %x ", combo);
return 0;
}
It will output 0xddccbbaa
Here's a more elegant function to do this :
unsigned int setByte(unsigned int input, unsigned char byte, unsigned int position)
{
if(position > sizeof(unsigned int) - 1)
return input;
unsigned int orbyte = byte;
input |= byte<<(position * 8);
return input;
}
Usage :
unsigned int combo = 0;
combo = setByte(combo, first_byte, 3);
combo = setByte(combo, second_byte, 2);
combo = setByte(combo, third_byte, 1);
combo = setByte(combo, fourth_byte, 0);
printf(" combo : %x ", combo);
unsigned int result;
result = ((first_byte <<(8*3)) | (second_byte <<(8*2)) | (third_byte <<(8*1)) | (fourth_byte))
You can extract the bytes and put them back in order as you're trying, that's a perfectly valid approach. But here are some other possibilities:
bswap, if you have access to it. It's an x86 instruction that does exactly this. It doesn't get any simpler. Similar instructions may exist on other platforms. Probably not good for a C assignment though.
Or, swapping adjacent "fields". If you have AABBCCDD and first swap adjacent 8-bit groups (get BBAADDCC), and then swap adjacent 16-bit groups, you get DDCCBBAA as desired. This can be implemented, for example: (not tested)
x = ((x & 0x00FF00FF) << 8) | ((x >> 8) & 0x00FF00FF);
x = ((x & 0x0000FFFF) << 16) | ((x >> 16) & 0x0000FFFF);
Or, a closely related method but with rotates. In AABBCCDD, AA and CC are both rotated to the left by 8 positions, and BB and DD are both rotated right by 8 positions. So you get:
x = rol(x & 0xFF00FF00, 8) | ror(x & 0x00FF00FF, 8);
This requires rotates however, which most high level languages don't provide, and emulating them with two shifts and an OR negates their advantage.
#include <stdio.h>
int main(void)
{
unsigned int input = 0xaabbccdd,
byte[4] = {0},
n = 0,
output = 0;
do
{
byte[n] = (input >> (8*n)) & 0xff;
n = n + 1;
}while(n < 4);
n = 0;
do
{
printf(" %d : %x\n", byte[n]);
n = n + 1;
}while (n < 4);
n = 0;
do
{
output = output << 8 | byte[n];
n = n + 1;
}while (n < 4);
printf(" output : %x ", output );
return 0;
}
You should try to avoid repeating code.
I am working on a function that will essentially see which of two ints is larger. The parameters that are passed are 2 32-bit ints. The trick is the only operators allowed are ! ~ | & << >> ^ (no casting, other data types besides signed int, *, /, -, etc..).
My idea so far is to ^ the two binaries together to see all the positions of the 1 values that they don't share. What I want to do is then take that value and isolate the 1 farthest to the left. Then see of which of them has that value in it. That value then will be the larger.
(Say we use 8-bit ints instead of 32-bit).
If the two values passed were 01011011 and 01101001
I used ^ on them to get 00100010.
I then want to make it 00100000 in other words 01xxxxxx -> 01000000
Then & it with the first number
!! the result and return it.
If it is 1, then the first # is larger.
Any thoughts on how to 01xxxxxx -> 01000000 or anything else to help?
Forgot to note: no ifs, whiles, fors etc...
Here's a loop-free version which compares unsigned integers in O(lg b) operations where b is the word size of the machine. Note the OP states no other data types than signed int, so it seems likely the top part of this answer does not meet the OP's specifications. (Spoiler version as at the bottom.)
Note that the behavior we want to capture is when the most significant bit mismatch is 1 for a and 0 for b. Another way of thinking about this is any bit in a being larger than the corresponding bit in b means a is greater than b, so long as there wasn't an earlier bit in a that was less than the corresponding bit in b.
To that end, we compute all the bits in a greater than the corresponding bits in b, and likewise compute all the bits in a less than the corresponding bits in b. We now want to mask out all the 'greater than' bits that are below any 'less than' bits, so we take all the 'less than' bits and smear them all to the right making a mask: the most significant bit set all the way down to the least significant bit are now 1.
Now all we have to do is remove the 'greater than' bits set by using simple bit masking logic.
The resulting value is 0 if a <= b and nonzero if a > b. If we want it to be 1 in the latter case we can do a similar smearing trick and just take a look at the least significant bit.
#include <stdio.h>
// Works for unsigned ints.
// Scroll down to the "actual algorithm" to see the interesting code.
// Utility function for displaying binary representation of an unsigned integer
void printBin(unsigned int x) {
for (int i = 31; i >= 0; i--) printf("%i", (x >> i) & 1);
printf("\n");
}
// Utility function to print out a separator
void printSep() {
for (int i = 31; i>= 0; i--) printf("-");
printf("\n");
}
int main()
{
while (1)
{
unsigned int a, b;
printf("Enter two unsigned integers separated by spaces: ");
scanf("%u %u", &a, &b);
getchar();
printBin(a);
printBin(b);
printSep();
/************ The actual algorithm starts here ************/
// These are all the bits in a that are less than their corresponding bits in b.
unsigned int ltb = ~a & b;
// These are all the bits in a that are greater than their corresponding bits in b.
unsigned int gtb = a & ~b;
ltb |= ltb >> 1;
ltb |= ltb >> 2;
ltb |= ltb >> 4;
ltb |= ltb >> 8;
ltb |= ltb >> 16;
// Nonzero if a > b
// Zero if a <= b
unsigned int isGt = gtb & ~ltb;
// If you want to make this exactly '1' when nonzero do this part:
isGt |= isGt >> 1;
isGt |= isGt >> 2;
isGt |= isGt >> 4;
isGt |= isGt >> 8;
isGt |= isGt >> 16;
isGt &= 1;
/************ The actual algorithm ends here ************/
// Print out the results.
printBin(ltb); // Debug info
printBin(gtb); // Debug info
printSep();
printBin(isGt); // The actual result
}
}
Note: This should work for signed integers as well if you flip the top bit on both of the inputs, e.g. a ^= 0x80000000.
Spoiler
If you want an answer that meets all of the requirements (including 25 operators or less):
int isGt(int a, int b)
{
int diff = a ^ b;
diff |= diff >> 1;
diff |= diff >> 2;
diff |= diff >> 4;
diff |= diff >> 8;
diff |= diff >> 16;
diff &= ~(diff >> 1) | 0x80000000;
diff &= (a ^ 0x80000000) & (b ^ 0x7fffffff);
return !!diff;
}
I'll leave explaining why it works up to you.
To convert 001xxxxx to 00100000, you first execute:
x |= x >> 4;
x |= x >> 2;
x |= x >> 1;
(this is for 8 bits; to extend it to 32, add shifts by 8 and 16 at the start of the sequence).
This leaves us with 00111111 (this technique is sometimes called "bit-smearing"). We can then chop off all but the first 1 bit:
x ^= x >> 1;
leaving us with 00100000.
An unsigned variant given that one can use logical (&&, ||) and comparison (!=, ==).
int u_isgt(unsigned int a, unsigned int b)
{
return a != b && ( /* If a == b then a !> b and a !< b. */
b == 0 || /* Else if b == 0 a has to be > b (as a != 0). */
(a / b) /* Else divide; integer division always truncate */
); /* towards zero. Giving 0 if a < b. */
}
!= and == can easily be eliminated., i.e.:
int u_isgt(unsigned int a, unsigned int b)
{
return a ^ b && (
!(b ^ 0) ||
(a / b)
);
}
For signed one could then expand to something like:
int isgt(int a, int b)
{
return
(a != b) &&
(
(!(0x80000000 & a) && 0x80000000 & b) || /* if a >= 0 && b < 0 */
(!(0x80000000 & a) && b == 0) ||
/* Two more lines, can add them if you like, but as it is homework
* I'll leave it up to you to decide.
* Hint: check on "both negative" and "both not negative". */
)
;
}
Can be more compact / eliminate ops. (at least one) but put it like this for clarity.
Instead of 0x80000000 one could say ie:
#include <limits.h>
static const int INT_NEG = (1 << ((sizeof(int) * CHAR_BIT) - 1));
Using this to test:
void test_isgt(int a, int b)
{
fprintf(stdout,
"%11d > %11d = %d : %d %s\n",
a, b,
isgt(a, b), (a > b),
isgt(a, b) != (a>b) ? "BAD!" : "OK!");
}
Result:
33 > 0 = 1 : 1 OK!
-33 > 0 = 0 : 0 OK!
0 > 33 = 0 : 0 OK!
0 > -33 = 1 : 1 OK!
0 > 0 = 0 : 0 OK!
33 > 33 = 0 : 0 OK!
-33 > -33 = 0 : 0 OK!
-5 > -33 = 1 : 1 OK!
-33 > -5 = 0 : 0 OK!
-2147483647 > 2147483647 = 0 : 0 OK!
2147483647 > -2147483647 = 1 : 1 OK!
2147483647 > 2147483647 = 0 : 0 OK!
2147483647 > 0 = 1 : 1 OK!
0 > 2147483647 = 0 : 0 OK!
A fully branchless version of Kaganar's smaller isGt function might look like so:
int isGt(int a, int b)
{
int diff = a ^ b;
diff |= diff >> 1;
diff |= diff >> 2;
diff |= diff >> 4;
diff |= diff >> 8;
diff |= diff >> 16;
//1+ on GT, 0 otherwise.
diff &= ~(diff >> 1) | 0x80000000;
diff &= (a ^ 0x80000000) & (b ^ 0x7fffffff);
//flatten back to range of 0 or 1.
diff |= diff >> 1;
diff |= diff >> 2;
diff |= diff >> 4;
diff |= diff >> 8;
diff |= diff >> 16;
diff &= 1;
return diff;
}
This clocks in at around 60 instructions for the actual computation (MSVC 2010 compiler, on an x86 arch), plus an extra 10 stack ops or so for the function's prolog/epilog.
EDIT:
Okay, there were some issues with the code, but I revised it and the following works.
This auxiliary function compares the numbers' n'th significant digit:
int compare ( int a, int b, int n )
{
int digit = (0x1 << n-1);
if ( (a & digit) && (b & digit) )
return 0; //the digit is the same
if ( (a & digit) && !(b & digit) )
return 1; //a is greater than b
if ( !(a & digit) && (b & digit) )
return -1; //b is greater than a
}
The following should recursively return the larger number:
int larger ( int a, int b )
{
for ( int i = 8*sizeof(a) - 1 ; i >= 0 ; i-- )
{
if ( int k = compare ( a, b, i ) )
{
return (k == 1) ? a : b;
}
}
return 0; //equal
}
As much as I don't want to do someone else's homework I couldn't resist this one.. :) I am sure others can think of a more compact one..but here is mine..works well, including negative numbers..
Edit: there are couple of bugs though. I will leave it to the OP to find it and fix it.
#include<unistd.h>
#include<stdio.h>
int a, b, i, ma, mb, a_neg, b_neg, stop;
int flipnum(int *num, int *is_neg) {
*num = ~(*num) + 1;
*is_neg = 1;
return 0;
}
int print_num1() {
return ((a_neg && printf("bigger number %d\n", mb)) ||
printf("bigger number %d\n", ma));
}
int print_num2() {
return ((b_neg && printf("bigger number %d\n", ma)) ||
printf("bigger number %d\n", mb));
}
int check_num1(int j) {
return ((a & j) && print_num1());
}
int check_num2(int j) {
return ((b & j) && print_num2());
}
int recursive_check (int j) {
((a & j) ^ (b & j)) && (check_num1(j) || check_num2(j)) && (stop = 1, j = 0);
return(!stop && (j = j >> 1) && recursive_check(j));
}
int main() {
int j;
scanf("%d%d", &a, &b);
ma = a; mb = b;
i = (sizeof (int) * 8) - 1;
j = 1 << i;
((a & j) && flipnum(&a, &a_neg));
((b & j) && flipnum(&b, &b_neg));
j = 1 << (i - 1);
recursive_check(j);
(!stop && printf("numbers are same..\n"));
}
I think I have a solution with 3 operations:
Add one to the first number, the subtract it from the largest possible number you can represent (all 1's). Add that number to the second number. If it it overflows, then the first number is less than the second.
I'm not 100% sure if this is correct. That is you might not need to add 1, and I don't know if it's possible to check for overflow (if not then just reserve the last bit and test if it's 1 at the end.)
EDIT: The constraints make the simple approach at the bottom invalid. I am adding the binary search function and the final comparison to detect the greater value:
unsigned long greater(unsigned long a, unsigned long b) {
unsigned long x = a;
unsigned long y = b;
unsigned long t = a ^ b;
if (t & 0xFFFF0000) {
x >>= 16;
y >>= 16;
t >>= 16;
}
if (t & 0xFF00) {
x >>= 8;
y >>= 8;
t >>= 8;
}
if (t & 0xf0) {
x >>= 4;
y >>= 4;
t >>= 4;
}
if ( t & 0xc) {
x >>= 2;
y >>= 2;
t >>= 2;
}
if ( t & 0x2) {
x >>= 1;
y >>= 1;
t >>= 1;
}
return (x & 1) ? a : b;
}
The idea is to start off with the most significant half of the word we are interested in and see if there are any set bits in there. If there are, then we don't need the least significant half, so we shift the unwanted bits away. If not, we do nothing (the half is zero anyway, so it won't get in the way). Since we cannot keep track of the shifted amount (it would require addition), we also shift the original values so that we can do the final and to determine the larger number. We repeat this process with half the size of the previous mask until we collapse the interesting bits into bit position 0.
I didn't add the equal case in here on purpose.
Old answer:
The simplest method is probably the best for a homework. Once you've got the mismatching bit value, you start off with another mask at 0x80000000 (or whatever suitable max bit position for your word size), and keep right shifting this until you hit a bit that is set in your mismatch value. If your right shift ends up with 0, then the mismatch value is 0.
I assume you already know the final step required to determine the larger number.
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.