shan bala Ответов: 8

Логика для обратного целого числа кусочек за кусочком


всем привет,

В одном интервью мне задали вопрос, Как перевернуть число int байт за байтом

например:

У меня есть целочисленное значение

int a=0x12 34 56 78;

я хочу обратить его вспять.

b=0x87 65 43 21;


может ли кто-нибудь плз дать логику для этого



Спасибо
Шань

phil.o

Непонятно: вы хотите изменить его бит за битом или байт за байтом? Потому что это совсем не одно и то же.

shan bala

Привет Фил,

извиняюсь,

постепенно

а также байт за байтом

int a=0x12 34 56 78

о/р
b=0x 78 56 34 12

OriginalGriff

Пожалуйста, обратите внимание: это не бит за бит своп: это кусочек за кусочком своп.
Битовая замена 8 в 1, 7-это Е, 6-это 6, 5-это А и так далее.

Vedat Ozan Oner

этот вопрос действительно привлек внимание :)

8 Ответов

Рейтинг:
62

OriginalGriff

Есть несколько способов сделать это: но самый простой, вероятно, использовать указатели:

#define byte unsigned char
int main()
    {
    int a = 0x12345678;
    int b;
    byte* pa = (byte*)&a;
    byte* pb = (byte*)&b;
    *(pb + 0) = *(pa + 3);
    *(pb + 1) = *(pa + 2);
    *(pb + 2) = *(pa + 1);
    *(pb + 3) = *(pa + 0);
    b = ((b >> 4) & 0x0F0F0F0F) | ((b & 0x0F0F0F0F) << 4); //ADDED This for nibble swapping
    printf( "%x:%x\n",a, b  );
    }


[edit]:doh: я тоже не заметил обмена клевками![/редактировать]


shan bala

привет,

Спасибо, это работает, можете ли вы объяснить логику

OriginalGriff

Ты ведь шутишь, правда?
Вы не понимаете, что это значит?
Это самый простой способ сделать это, там нет никакой сложности вообще...

Maciej Los

+5!

Рейтинг:
2

bling

static unsigned long nibble_pivot(unsigned long value)
{
    // word swap (pivot)
    value = (value << 16) | (value >> 16);
    // byte swap
    value = ( (value & 0xFF00FF00UL) >> 8) | ( (value & 0x00FF00FFUL) << 8);
    // nibble swap
    value = ( (value & 0xF0F0F0F0UL) >> 4) | ( (value & 0x00F0F0F0FUL) << 4);
    return value;
}

int main(int argc, char* argv[])
{
    fprintf(stdout, "%08lX -> %08lX\n", 0x12345678UL, nibble_pivot(0x12345678UL));
    getchar();
    return 0;
}


Рейтинг:
1

Vedat Ozan Oner

в дополнение к OriginalGriff, здесь есть побитовый реверс:

#include <stdio.h>

int main() {
 int i;

 // set size of it as bit count
 int sizeint=sizeof(int)*8;
 // given number
 unsigned int given=~2;
 // reversed value
 unsigned int reversed=0;
 // bit test
 unsigned int test=1;

 // for each bit
 for(i=0; i<sizeint; i++) {
   // test if that bit set
   if(given&test)
     reversed|=1;
   // next bit
   test<<=1;
   // bit shift to prepare next
   if(test)
    reversed<<=1;
 }
 printf("given=%x, reversed=%x\n", given, reversed);

 return 0;
}


Рейтинг:
1

CPallini

#include <stdio.h>

struct Nibble
{
  unsigned int u0 : 4;
  unsigned int u1 : 4;
  unsigned int u2 : 4;
  unsigned int u3 : 4;
  unsigned int u4 : 4;
  unsigned int u5 : 4;
  unsigned int u6 : 4;
  unsigned int u7 : 4;
};

union IntNibble
{
  int i;
  struct Nibble n;
};

int main()
{
  union IntNibble x,y;

  x.i = 0x12345678;

  y.n.u0 = x.n.u7;
  y.n.u1 = x.n.u6;
  y.n.u2 = x.n.u5;
  y.n.u3 = x.n.u4;
  y.n.u4 = x.n.u3;
  y.n.u5 = x.n.u2;
  y.n.u6 = x.n.u1;
  y.n.u7 = x.n.u0;

  printf("%X\n", y.i);

  return 0;
}


Рейтинг:
1

CPallini

#include <stdio.h>
#include <stdlib.h>
int main()
{
  int x = 0x12345678;
  int y;
  int i;
  char a[9];
  sprintf(a, "%08X", x);
  for (i=0; i<4; ++i)
  {
    char b = a[7-i];
    a[7-i] = a[i];
    a[i] = b;
  }
  y = strtoul(a,NULL,16);
  printf("%X\n", y);
  return 0;
}


Рейтинг:
1

bling

Безвозмездное использование встроенной сборки ...

static unsigned long nibble_pivot(unsigned long value)
{
    __asm
    {
        mov eax, value;
        rol eax, 16;
        mov edx, eax;
        and eax, 0xFF00FFUL;
        and edx, 0xFF00FF00UL;
        shr edx, 8;
        shl eax, 8;
        or eax, edx;
        mov edx, eax;
        and eax, 0xF0F0F0FUL;
        and edx, 0xF0F0F0F0UL;
        shr edx, 4;
        shl eax, 4;
        or eax, edx;
        mov value, eax
    }
    return value;
}


Рейтинг:
1

Member 14885652

Пустота обратного()
{
unsigned int a=0x12345678;
a=((a&0x0000000F)< & lt;28)| //(0x80 00 00 00) |
((a&0x000000F0)<<20)| //(0x07 00 00 00) |
((a&0x00000F00)<<12)| // (0x00 60 00 00) |
((a&0x0000F000)< & lt;4)| // (0x00 05 00 00) |
((a&0x000F0000)>>4)| // (0x00 00 40 00) |
((a&0x00F00000)>>12)| //(0x00 00 03 00) |
((a&0x0F000000)>>20)| // (0x00 00 00 20) |
((a&0xF0000000)> & gt;28); //(0x00 00 00 01)
printf("%x\n",a);
}
Выход:87654321


Рейтинг:
0

CPallini

int rev_nibbles(int x)
{
  int y = 0;
  while (x)
  {
    y <<= 4;
    y |= x & 0xF;
    x >>= 4;
  }
  return y;
}


Maciej Los

+5!

CPallini

Спасибо.