CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 12 of 12

Thread: Nibble in bytes

  1. #1
    Join Date
    Apr 2002
    Location
    Mumbai,India
    Posts
    567

    Nibble in bytes

    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

  2. #2
    Join Date
    Apr 2003
    Location
    India
    Posts
    33

    Nibble

    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 )
    Cope with change....Respect change.....Drive change.....!!!

  3. #3
    Join Date
    Sep 2003
    Location
    Forever Gone... For Now...
    Posts
    1,515
    a byte is nearly always eight bits, a nibble is nearly always four bits
    Then perhaps a more poignant interview question would be "When is a byte not eight bits", and "When is a nibble not four bits"?
    Thought for the day/week/month/year:
    Windows System Error 4006:
    Replication with a nonconfigured partner is not allowed.

  4. #4
    Join Date
    Apr 2003
    Location
    India
    Posts
    33
    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 ?????
    Cope with change....Respect change.....Drive change.....!!!

  5. #5
    Join Date
    Sep 2003
    Location
    Forever Gone... For Now...
    Posts
    1,515
    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.

    Take it easy man
    How many bytes did PacMan consume?
    Thought for the day/week/month/year:
    Windows System Error 4006:
    Replication with a nonconfigured partner is not allowed.

  6. #6
    Join Date
    Jun 2003
    Location
    Armenia, Yerevan
    Posts
    720
    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);
    }

  7. #7
    Join Date
    Apr 2003
    Posts
    893
    Originally posted by vicodin451
    How many bytes did PacMan consume?
    I think 4 bytes...

  8. #8
    Join Date
    Apr 2003
    Location
    India
    Posts
    33
    ??
    Cope with change....Respect change.....Drive change.....!!!

  9. #9
    Join Date
    Apr 2002
    Location
    Mumbai,India
    Posts
    567
    thanks all
    AvDav could you explain me the code which u have shown specially the macro code
    Hope for the help
    Vishal

  10. #10
    Join Date
    Jun 2002
    Location
    Germany
    Posts
    1,557
    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;
    }
    You're gonna go blind staring into that box all day.

  11. #11
    Join Date
    Jun 2003
    Location
    Armenia, Yerevan
    Posts
    720
    '^' 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;

    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
    In macros x == (bt).bt_.n1 and y == (bt).bt_.n2;

    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++.
    Code:
    template<class T> inline void swap(T &a, T &b)
    {
     T tmp = a;
     a = b;
     b = tmp;
    }
    Hope it is clear enough.
    Last edited by AvDav; October 29th, 2003 at 01:03 PM.

  12. #12
    Join Date
    Dec 2002
    Posts
    47
    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

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured