How can I see the bytes/bits of a variable in C? In terms of binary, just zeros and ones.
My problem is that I want to test to see if any zeros exist in the most significant byte of variable x. Any help would be appreciated.
Use the logical AND operator &. For example:
char c = ....
if ( (c & 0xFF) == 0xFF) ... // test char c for zeroes
You may want to use shifts and macros to automate it, instead of using numeric constants, because for different types you'll need different values to test the MSB. You can get the value for shifts using sizeof.
// test MSB of an int for zeroes
int i = ...
if ( ( i & (0xFF << 8*(sizeof(int)-1))) == (0xFF<<8*(sizeof(int)-1))) ...
You can use following test
var & (1 << N)
To check if bit N is set in var. Most significant bit depends on the datatype of var.
Print the memory byte by byte, i.e. from 0 to sizeof(x) (if x happens to be your variable). Then, when printing each byte, print all eight bits individually.
if(x & 0x80) // assuming x is a byte(char type)
{
// msb is set
}
Related
Is there a way to access certain parts of a hexadecimal number in C?
I want to write a function that takes in a hexadecimal number and negates it, but leaves the least significant byte unchanged. Example: 0x87654321 should become 0x789ABC21.
I've tried to somehow save the LSB and then apply it to the negated x, but my problem is that my mask gets applied to all bytes. I could hard code it for a specific value, but obviously that's not what I want.
void b(int x) {
int temp = x & 0xFF; // temp is all 0 with the LSB being the same as x's
x = ~x; // this negates x
// one of a couple of attempts I tried thus far:
// x = (x & 0x00) | temp;
// idea: change x's LSB to 00 and OR it with temp,
// changing x's LSB to temp's LSB
}
I'd appreciate if you don't post code for the solution, but rather just answer whether there is a way to apply bit operations to specific sections of a hexadecimal number, or how I could possibly solve this.
In general you can operate on specific bits of a value by using a mask.
A mask is bit-pattern with 1s where you want to operate and 0s where you don't.
It seems like you need 3 operations: extract lowest byte, negate, restore lowest byte. You can figure out negation, so I'll just talk about extracting a bit-field and restoring an extracted bit-field.
To extract specified bits, use a mask with 1s for the desired bits and use the bitwise and operator &. The and operator sets 0s for all 0s of the mask, and where the mask is 1, it copies the bits from the other argument. If you need to examine this value elsewhere in your program, it may also be convenient to right-shift >> the value down to the lowest position (so it's easier to lookup in tables).
To restore saved bits, shift back up if you shifted it down earlier. Then clear those bits from the value, and use inclusive-or | as a bitwise sum of all one bits. To clear the bits from the value, use the inverse of the mask from the first operation. Ie. y = x & 0xf saves a nibble, x & ~0xf clears that nibble, (x & ~0xf) | y recombines to the same original x.
Edit:
If the piece you're extracting is not in the lowest position, say the second byte (LSB) from a 32 bit unsigned integer, then it may be useful to shift the extracted value to the zero position to work with it.
x = 0x12345678;
y = x & 0xFF00; // == 0x5600
y >>= 8; // == 0x56
But if you do this then you have to shift it back to the correct position (of course) before updating the larger value with a new value for the bitfield.
x = (x & ~0xFF00) | (y << 8);
If I correctly understood the question, seems like it would be something like this (untested).
void b(int x) {
return (~x & ~0xFF) | (x & 0xFF);
}
I've found a way to manipulate a chosen byte. (!!! This would be homework 2.60 of CS:APP !!!)
If 0x12345678 is a given hexadecimal value of type, say int, then doing this will allow me to change the ith byte:
int x = 0x12345678;
unsigned char* xptr = (unsigned char*) &x;
xptr[i] = 0; // say i=2, then this would yield: 0x120045678
Now, if I want to add a value in the position of byte i, say 0xAB, I'd do what luser droog already mentioned:
int temp = 0xAB;
temp = temp << i*8; // say i=2, then this would yield: 0x00AB0000
x = x | temp; // this yields the desired result 0x12AB3456
I have (not mine) a program that reads long values from a data-file.
I can change the numbers in the data-file and I can do s.th. with the number the program has read from the data-file.
Now I want to write 2 integer-values (2*4 byte) in the data-file instead of one (small) long-value (8 byte).
What do I have to do with the number I get in the program to 'split' that into the two initial integer-values?
What I read is s.th. like 54257654438765. How do I split that?
That program offers me some (c-like) bitwise operations:
x = x << y; // left shift
x = x >> y; // right shift
b = ((x & y) != 0); // Bitwise AND
b = ((x | y) != 0); // Bitwise OR
b = x ^ y; // Bitwise Exclusive Operation OR
But these operators are working in that program only with integer- not long-values and I assume that 2 integers together get bigger than the highest possible integer +-2'147'483'647).
Is there a numeric approach (from the value I see) to get back the two int-values?
I have never tried that and I appreciate any hint!
That is a easy one. You got your 64-bit value. The upper 32-bit is one value, the lower another.
The trick is to get the values into position to a cast to a 32-bit integer works. So casting your 64-bit value to a integer and storing it in a integer variable, will give you the lower 32-bit value right away.
For the upper value you need to do some shifting. You need to move the upper values by 32bit to the right to get them into position.
So basically:
uint64 longValue = /* Your long value. */;
uint32 firstIntValue = (uint32) longValue;
uint32 secondIntValue = (uint32) (longValue >> 32);
As the cast will discard all bits not fitting into the new variable that should work just fine.
EDIT:
And as requested by comment. Also the other way round:
uint64 longValue = secondIntValue;
longValue = longValue << 32; /* If its C: longValue <<= 32; */
longValue = longValue | firstIntValue; /* If its C: longValue |= firstIntValue; */
The idea here is to first put the the integer that is supposed to end up in the higher bits to the 64-bit storage and move them with the shift to the up bits. After that place the lower value with a OR operation in the lower bits. You can't perform a simple assignment in the last operation because that would kill the upper bits.
Just as additional information. You can get around all that shifting entirely in case you are able to use unions and structs in the language you are using. If its plain C that is possible.
I'm trying to learn a bit about emulation and I'm trying to think of how I can decode opcodes. Each opcode is a short data type, 16 bits. I'd like to be able to compare only specific sets of 4 bits. For example: there are multiple opcodes that start with 00, such as 0x00E0.
I'd like to be able to compare each of these values in either bit or hexidecimal form. I was thinking maybe something along the lines of bit shifting to bump of everything else off so that the bits I don't care about would zero out. That may cause issues for the center bits and will require additional steps. What kind of solutions do you guys use for a problem like this?
Use a bit mask, which has the bits set that you care about. Then use the & operator to zero out everything that you don't care about. For instance, say we want to compare the lowest four bits in a and b:
uint16 mask = 0x000f;
if ((a & mask) == (b & mask)) {
// lowest 4 bits are equal
}
This is simple bit manipulation. You can mask the relevant bits with
int x = opcode & 0x00f0;
and compare the resulting value
if (x == 0x00e0) {
/* do something */
}
you can easily create the mask of "nbits" and and shift "pos" number of bits and do comparision
uint32_t mask = ~((~0) << nbits);
if( (num(mask << pos)) == 0x00e0 ) {
/* Do something */
}
I'm trying to understand the following function which decides whether a bit is on:
int isBitISet( char ch, int i )
{
char mask = 1 << i ;
return mask & ch ;
}
First, why do I get a char? for ch=abcdefgh and i=5 the function suppose to return the fifth bit from the right (?) , d. so mask=00000001<<5=00100000, and 00100000 & abcdefgh = 00c00000.
Can you please explain me how come we get char and we can do all these shifts without any casting? how come we didn't get the fifth bit and why the returned value is really the Indication whether the bit is on or not?
Edit: the 'abcdefg' are just a symbols for the bits, I didn't mean to represent a string in a char type.
I used to think of a char as 'a' and not as an actual 8 bits, so probably this is the answer to my first question.
It won't give you the fifth bit. Binary numbers start at 20, so the first bit is actually indexed with 0, not with 1. It will give return you sixth bit instead.
Examples:
ch & (1 << 0); // first bit
ch & (1 << 1); // second bit
ch & ((1 << 3) | (1 << 2)); // third and fourth bit.
Also, a char is only an interpretation of a number. On most machines it has a size of 8 bit, which you can either interpret as a unsigned value (0 to 255) or signed value (-128 to 127). So basically it's an integer with a very limited range, thus you can apply bit shifting without casting.
Also, your function will return an integer value that equals zero if and only if the given bit isn't set. Otherwise it's a non-zero value.
The function may return a char, because the input it works on is also a char only. You certainly can not pass in ch=abcdefgh, because that would be a string of 8 chars.
You can do shifts on chars, because C allows to do it. char is just an 8-bit integer type so there's no need to disallow it.
You are right about the fact, that isBitISet(abcdefgh, 5) returns 00c00000 if the letters a, b, etc. are bits in the binary representation of numbers.
The return value is not the fifth bit from the right, it is the same number as in the input, but with all the bits but the fifth bit zeroed.
You also have to remember that numbering of bits goes from zero, so the fifth bit being c is correct, just as that the zeroth bit is h.
This example uses an integer type to represent a boolean value. This is common in C code prior to C99, as C didn't have the bool type.
If you treat your return value as a boolean value, remember that everything non-zero is true, and zero is false. Hence, the output of isBitISet is true for C if bit i is set, and false otherwise.
You should know by now that in computers, everything starts with 0. That is, bit number 5 is in fact the sixth bit (not the fifth).
Your analysis is actually correct, if you give it abcdefgh and 5, you get 00c00000.
When you do the "and":
return mask & ch;
since mask has type int, ch will also automatically be cast to int (same way as many other operators). That's why you don't need explicit casting.
Finally, the result of this function is in the form 0..0z0..0. If z, the bit you are checking for is 0, this value is 0 which is false as long as an if is concerned. If it is not zero, then it is true for an if.
Do:
return 0 != (mask & ch) ;
if you want a bool (0x00000000 or 0x00000001) return. mask & ch alone will give you the bit you're asking about at correct position.
(others said more than enuff about i=5 being sixth bit)
First of all, this function does not return the i-th bit, but tells you if that bit is on or off.
The usage of char mask is implementation depend here. Simply defines an 8-bit mask since the value on which to apply this mask is a char.
Why would you need a cast when 1 is a char? i is only an value for << operator.
ch=abcdefgh makes no sense as an input. ch is char, so ch can only be one character.
The working is as follows: first you construct a mask to zero all the bits you don't need. So for example if the input is ch = 204 (ch = 11001100) and we want to know if the 6th bit is on, so i = 5. So mask = 1 << 5 = 00100000. Then this mask is applied to the value with an AND operation. This will zero everything except the bit in question: 11001100 & 00100000 = 00000000 = 0. As 0 is false in C, then 6th bit is not set. Another example on same ch input and i = 6: mask = 1 << 6 = 01000000; 11001100 & 01000000 = 01000000 = 64, which is not 0, and thus true, so 7th bit is set.
I use a byte to store some flag like 10101010, and I would like to know how to verify that a specific bit is at 1 or 0.
Here's a function that can be used to test any bit:
bool is_bit_set(unsigned value, unsigned bitindex)
{
return (value & (1 << bitindex)) != 0;
}
Explanation:
The left shift operator << creates a bitmask. To illustrate:
(1 << 0) equals 00000001
(1 << 1) equals 00000010
(1 << 3) equals 00001000
So a shift of 0 tests the rightmost bit. A shift of 31 would be the leftmost bit of a 32-bit value.
The bitwise-and operator (&) gives a result where all the bits that are 1 on both sides are set. Examples:
1111 & 0001 equals 0001
1111 & 0010 equals 0010
0000 & 0001 equals 0000.
So, the expression:
(value & (1 << bitindex))
will return the bitmask if the associated bit (bitindex) contains a 1
in that position, or else it will return 0 (meaning it does not contain a 1 at the assoicated bitindex).
To simplify, the expression tests if the result is greater than zero.
If Result > 0 returns true, meaning the byte has a 1 in the tested
bitindex position.
All else returns false meaning the result was zero, which means there's a 0 in tested bitindex position.
Note the != 0 is not required in the statement since it's a bool, but I like to make it explicit.
As an extension of Patrick Desjardins' answer:
When doing bit-manipulation it really helps to have a very solid knowledge of bitwise operators.
Also the bitwise "AND" operator in C is &, so you want to do this:
unsigned char a = 0xAA; // 10101010 in hex
unsigned char b = (1 << bitpos); // Where bitpos is the position you want to check
if(a & b) {
//bit set
}
else {
//not set
}
Above I used the bitwise "AND" (& in C) to check whether a particular bit was set or not. I also used two different ways of formulating binary numbers. I highly recommend you check out the Wikipedia link above.
You can use an AND operator. The example you have: 10101010 and you want to check the third bit you can do: (10101010 AND 00100000) and if you get 00100000 you know that you have the flag at the third position to 1.
Kristopher Johnson's answer is very good if you like working with individual fields like this. I prefer to make the code easier to read by using bit fields in C.
For example:
struct fieldsample
{
unsigned short field1 : 1;
unsigned short field2 : 1;
unsigned short field3 : 1;
unsigned short field4 : 1;
}
Here you have a simple struct with four fields, each 1 bit in size. Then you can write your code using simple structure access.
void codesample()
{
//Declare the struct on the stack.
fieldsample fields;
//Initialize values.
fields.f1 = 1;
fields.f2 = 0;
fields.f3 = 0;
fields.f4 = 1;
...
//Check the value of a field.
if(fields.f1 == 1) {}
...
}
You get the same small size advantage, plus readable code because you can give your fields meaningful names inside the structure.
If you are using C++ and the standard library is allowed, I'd suggest storing your flags in a bitset:
#include <bitset>
//...
std::bitset<8> flags(someVariable);
as then you can check and set flags using the [] indexing operator.
Nobody's been wrong so far, but to give a method to check an arbitrary bit:
int checkBit( byte in, int bit )
{
return in & ( 1 << bit );
}
If the function returns non-zero, the bit is set.
byte THIRDBIT = 4; // 4 = 00000100 i.e third bit is set
int isThirdBitSet(byte in) {
return in & THIRDBIT; // Returns 1 if the third bit is set, 0 otherwise
}
Traditionally, to check if the lowest bit is set, this will look something like:
int MY_FLAG = 0x0001;
if ((value & MY_FLAG) == MY_FLAG)
doSomething();
You can do as Patrick Desjardins says and you make a bit-to-bit OR to the resulting of the previous AND operation.
In this case, you will have a final result of 1 or 0.
Use a bitwise (not logical!) AND to compare the value against a bitmask.
if (var & 0x08) {
/* The fourth bit is set */
}