I was asked in an interview the following question
For which i seek your help
Write a macro in C for swapping two nibbles in a byte.
also what is is this nibble" ?:(
thanks
vishal
Printable View
I was asked in an interview the following question
For which i seek your help
Write a macro in C for swapping two nibbles in a byte.
also what is is this nibble" ?:(
thanks
vishal
Nibble is 1/2 of a byte.( a byte is nearly always eight bits, a nibble is nearly always four bits and can therefore be represented by one hex digit )
Then perhaps a more poignant interview question would be "When is a byte not eight bits", and "When is a nibble not four bits"?Quote:
a byte is nearly always eight bits, a nibble is nearly always four bits
Take it easy man....hope u could understand what i meant is..!!
i know..byte is 8 bit and nibble is 4 bit... enuff na ?????
Your reply was directed to someone who didn't know what a nibble was. You basically said "sometimes, a nibble is...". This is barely helpful.
How many bytes did PacMan consume?Quote:
Take it easy man
Code:#define swap(bt) (bt).bt_.n2^=(bt).bt_.n1^((bt).bt_.n1^=(bt).bt_.n1^(bt).bt_.n2)
union byte
{
struct
{
unsigned char n1:4, n2:4;
} bt_;
unsigned char bt;
};
void main()
{
union byte bt;
bt.bt = 0xfe;
swap(bt);
}
I think 4 bytes...Quote:
Originally posted by vicodin451
How many bytes did PacMan consume?
??
thanks all
AvDav could you explain me the code which u have shown specially the macro code
Hope for the help
Vishal
VNS,
All this talk of nibbles and bytes really makes me hungry. Beyond the interview question, I prefer to set up these kinds of manipulations in a generalized and flexible fashion.
I want you to look at the following templated code sample. It might appear confusing at first but it is really rather straight forward. I think that you might get some ideas from the sample.
Sincerely, Chris.
:)
Code:
#include <iostream>
#include <limits>
typedef unsigned long int DWORD;
typedef unsigned short int WORD;
typedef unsigned char BYTE;
template <typename T> T T_BITS(const int bit, const int count)
{
return (
::std::numeric_limits<T>::max() >>
(::std::numeric_limits<T>::digits - (count))
) << bit;
}
template <typename T> T T_SWAP(const T t)
{
T lo = t & T_BITS<T>(0,
::std::numeric_limits<T>::digits / 2);
T hi = t & T_BITS<T>(::std::numeric_limits<T>::digits / 2,
::std::numeric_limits<T>::digits / 2);
return (lo << ::std::numeric_limits<T>::digits / 2)
| (hi >> ::std::numeric_limits<T>::digits / 2);
}
int main(int argc, char* argv[])
{
const BYTE b = 0xf1;
const BYTE b_swap = T_SWAP(b);
const WORD w = 0x1234;
const WORD w_swap = T_SWAP(w);
const DWORD d = 0x1111aaaa;
const DWORD d_swap = T_SWAP(d);
return 0;
}
'^' is bitwise xor (eXclusive or) operation:
a xor b = 1 //if only one of a and b is 1, otherwise 0.
in other words: a xor b == [a and (not b)] or [(not a) and b].
Note that: [(a xor b) xor a] == b, and [(a xor b) xor b] == a;
In macros x == (bt).bt_.n1 and y == (bt).bt_.n2;Code:unsigned char x = 10, y= 5;
y^=x^(x^=x^y); //[1]
//x^=x^y --> new x value will be y.
//left x operand in [1] holds his old value.
//so new value in y will be x^y_old^y_old == x
union was used for access the byte and his nibbles.
union A
{
varType1 var1;
varType2 var2;
.
.
varTypeN varN;
}
sizeof(A) == max(sizeof(varTypei));
changing each variable in union will cause change its all variables.
Also this way of swapping will cause more assembly instructions but without temporary variable (if you'll use the tmp version in macro you can get redefinitions) if compare with swapping using the temorary variable.
IMHO macros is bad idea comparing with inline function way, if use C++.
Hope it is clear enough.Code:template<class T> inline void swap(T &a, T &b)
{
T tmp = a;
a = b;
b = tmp;
}
ANSI C style ...
unsigned char swap(unsigned char byte)
{
/* keep holds upper 4 bits. */
unsigned char keep = byte >> 4;
keep = keep & 0xF; /* unnecessary */
/* byte is now lower 4 bits. */.
byte = byte & 0xF;
/* shift lower 4 bits to occupy upper 4 bits. */
byte = byte << 4;
/* merge nibbles together. */
byte = byte | keep;
return byte;
}
Isn't there a ROL (rotate left) or ROR (rotate right) instruction in x86? Probably not correct, but close enough to illustrate:
unsigned char swap(unsigned char nibbles)
{
__asm move al, byte prt nibbles;
__asm mov cl, 4;
__asm rol al, cl;
__asm mov byte ptr nibbles, al
return nibbles;
}
-rick