On-line: гостей 0. Всего: 0 [подробнее..]
Программисты всех стран, объединяйтесь!

АвторСообщение



ссылка на сообщение  Отправлено: 27.11.14 13:00. Заголовок: Bitwise operators


Looking for some help with bitwise operators, I read the documentation and everything I could find about them but I don't really have a basic understanding on how to apply them properly.

Say I have this problem which is from a previous lab:

3. Nibbles A nibble is a group of 4 bits. Write a function that given an unsigned n
  • a) returns the value with the nibbles placed in reverse order

  • b) returns the value with the bits in each nibble reversed


  • Can somebody help me with a solution for it ? I don't really need the code commentated since I am confident I can read it, I just don't know how to write something like this.


    Спасибо: 0 
    ПрофильЦитата Ответить
    Ответов - 6 [только новые]





    ссылка на сообщение  Отправлено: 27.11.14 13:31. Заголовок: It is not difficult ..


    It is not difficult to write the first function if to place the result in other number that is to use operation reverse-copy. Here is a demonstrative program

    I suppose that the function should be written in C.
     
    #include <stdio.h>

    unsigned int reverse_nibbles( unsigned int x )
    {
    unsigned int y = 0;

    for ( size_t i = 0; i < 2 * sizeof( unsigned int ); i++ )
    {
    y <<= 4;
    y |= x & 0xF;
    x >>= 4;
    }

    return y;
    }

    int main(void)
    {
    unsigned int x = 0x12345678;
    unsigned int y = reverse_nibbles( x );

    printf( "%x\t%x\n", x , y );

    return 0;
    }


    The output is
     
    12345678 87654321



    Спасибо: 0 
    ПрофильЦитата Ответить



    ссылка на сообщение  Отправлено: 27.11.14 14:34. Заголовок: Yes, C is the langua..


    Yes, C is the language sorry for not mentioning it, I forgot.
    Anyway, seems I need to ask some stuff about this part:

    y <<= 4;
    y |= x & 0xF;
    x >>= 4;

    First, we shift y 4 bits to the left, why do we need to do this every iteration ?
    Then we OR y with the result of x & 0xF. 0xF is 1111 in binary so that means x remains unchanged since 1 with 1 is 1 and 0 with 1 is 0, but why exactly did we have to mask it with 0xF first ? Because in my head this doesn't change anything. Then y |= x means we reverse every bit of x, is that what happens ?
    Then we right shift x by 4. In case of 0000 1000 (8, say it's stored as just 1 byte), wouldn't right shifting by 4 produce 0000 0000 ?
    And why do you pass x as a hex value ?

    One more thing, say we have x = 8 (1000 binary) and we want to print the binary representation of it. What I saw people do is shift left by 3 (let's forget about all those 0's in front) so we get 0000 and then compare it with 1 as lets' say x & 1 ? printf("1") :printf(" 0"). I understand that AND with 1 doesn't change anything but what value gets received from x & 1 and why is is evaluated to true/false ? Doesn't it change the whole bit sequence ?


    I don't know why this stuff seems to be so hard to me, I think I don't get a basic concept here....



    Спасибо: 0 
    ПрофильЦитата Ответить



    ссылка на сообщение  Отправлено: 27.11.14 14:57. Заголовок: Taking into account ..


    Taking into account that the initial value of x in the program if to print it in hex looks like
     
    12345678

    let's assume that y already contains the last digit of x that is y looks like
     
    00000008

    That to get the last digit of x x was shifted right at the end of the first iteration of the loop. That is we now have (before the second iteration of the loop)
     
    x: 01234567
    y: 00000008


    Now that to append the current last digit of x that is 7 to y we need to shift left y
     
    y <<= 4

    Now y will look like
     
    00000080

    Then we need to extract this last digit of x. If binary operator & will be applied to x
     
    x & 0xF

    then the value of the expression will be
     
    00000007


    So we have
     
    00000080 <== the current value of y
    00000007 <== the value of expression x & 0xF

    and the result will be
     
    00000080
    |
    00000007
    ======
    00000087 <== y |= x & 0xF


    All will be repeated in the next iteration of the loop.

    Try to do this yourself using a paper and pencil





    Спасибо: 0 
    ПрофильЦитата Ответить



    ссылка на сообщение  Отправлено: 27.11.14 15:11. Заголовок: So, basically, in yo..


    So, basically, in your example, every number is a nibble actually, right ? Thanks for this, I think I got this part.

    Could you give me some logic on this aswell ?

    Say we have x = 8 (1000 binary) and we want to print the binary representation of it. What I saw people do is shift left by 3 (let's forget about all those 0's in front) so we get 0000 and then compare it with 1 as lets' say x & 1 ? printf("1") :printf(" 0"). I understand that AND with 1 doesn't change anything but what value gets received from x & 1 and why is is evaluated to true/false ? Doesn't it change the whole bit sequence ?

    Спасибо: 0 
    ПрофильЦитата Ответить



    ссылка на сообщение  Отправлено: 27.11.14 15:24. Заголовок: After shifting x = 0..


    After shifting x = 0b1000 by three to the right we will get 0b0001 (not 0b0000).

    The result of expression x & 1 (after shifiting x by 3 to the right) will be 0b0001. If x would be equal to 0b0000 then the result of expression x & 1 would be equal to 0b0000.

    So to print binary representation of x that is equal to 0b1000 you could write the loop
     
    for ( size_t i = 4; i != 0; )
    {
    printf( "&d", x >> --i );
    }
    .


    Спасибо: 0 
    ПрофильЦитата Ответить



    ссылка на сообщение  Отправлено: 30.11.14 09:00. Заголовок: A straightforward ap..


    A straightforward approach to the second function can look the following way
     
    unsigned int swap_nibbles( unsigned int x )
    {
    for ( unsigned int y = 0x0F; y; y <<= 4 )
    {
    unsigned int tmp = ( x & y ) << 4 ;
    x &= ~y;
    y <<= 4;
    tmp |= ( x & y ) >> 4;
    x &= ~y;
    x |= tmp;
    }
    }


    Though it is not an elegant solution however it works.
    Below a demonstrative program that uses the both functions.
     
    #include <stdio.h>

    unsigned int reverse_nibbles( unsigned int x )
    {
    unsigned int y = 0;

    for ( size_t i = 0; i < 2 * sizeof( unsigned int ); i++ )
    {
    y <<= 4;
    y |= x & 0xF;
    x >>= 4;
    }

    return y;
    }

    unsigned int swap_nibbles( unsigned int x )
    {
    for ( unsigned int y = 0x0F; y; y <<= 4 )
    {
    unsigned int tmp = ( x & y ) << 4 ;
    x &= ~y;
    y <<= 4;
    tmp |= ( x & y ) >> 4;
    x &= ~y;
    x |= tmp;
    }

    return x;
    }

    int main(void)
    {
    unsigned int x = 0x12345678;

    printf( "%x\t%x\n", x , reverse_nibbles( x ) );
    printf( "%x\t%x\n", x , swap_nibbles( x ) );


    return 0;
    }


    The program output is
     
    12345678 87654321
    12345678 21436587



    Спасибо: 0 
    ПрофильЦитата Ответить
    Ответ:
    1 2 3 4 5 6 7 8 9
    большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

    показывать это сообщение только модераторам
    не делать ссылки активными
    Имя, пароль:      зарегистрироваться    
    Тему читают:
    - участник сейчас на форуме
    - участник вне форума
    Все даты в формате GMT  3 час. Хитов сегодня: 2
    Права: смайлы да, картинки да, шрифты да, голосования нет
    аватары да, автозамена ссылок вкл, премодерация откл, правка нет