2016-10-20 5 views
2

Я застреваю в XORing 32-битное целое с ним. Я должен XOR 4 8-битные части целых чисел. Я понимаю, как это работает, но без сохранения целого числа в любом месте, я не понимаю, как это сделать.XORing 32-битное целое с самим собой

Я подумал об этом, и я подумываю использовать двоичные операторы сдвига влево и вправо, чтобы разделить 32-битное целое на 4 части на XOR. Например, если бы я был использовать 8-разрядное целое число, я хотел бы сделать что-то вроде этого:

int a = <some integer here> 
(a << 4)^(a >> 4) 

До сих пор он не работает так, как я думал, что это будет работать.

Вот часть моего кода:

else if (choice == 2) { 
    int bits = 8; 

    printf("Enter an integer for checksum calculation: "); 
    scanf("%d", &in); 
    printf("Integer: %d, ", in); 

    int x = in, i; 
    int mask = 1 << sizeof(int) * bits - 1; 

    printf("Bit representation: "); 

    for (i = 1; i <= sizeof(int) * bits; i++) { 
     if (x & mask) 
      putchar('1'); 
     else 
      putchar('0'); 

     x <<= 1; 
     if (! (i % 8)) { 
      putchar(' '); 
     } 
    } 
    printf("\n"); 

} 

Вот пример вывода:

What type of display do you want? 
    Enter 1 for character parity, 2 for integer checksum: 2 
    Enter an integer for checksum calculation: 1024 
    Integer: 1024, Bit representation: 00000000 00000000 00000100 00000000 
    Checksum of the number is: 4, Bit representation: 00000100  
+2

Общие рекомендации: не сдвигайте знаковые целые числа по всей ширине. Если может быть реализована определенная реализация или даже вызвать неопределенное поведение (подробности см. В стандарте). И если вам нужны 32-битные целые числа, используйте стандартные типы фиксированной ширины. – Olaf

+1

Я немного смущен тем, что вы просите, потому что я не вижу XOR в вашей программе, кроме не относящегося к делу фрагмента, который вы показали над программой. Возможно, вы пытаетесь сделать что-то вроде 'a = (a << 4)^(a >> 4)', что является неопределенным поведением из-за точек последовательности. – paddy

+0

'for (i = 1; i <= sizeof (int) * bits; i ++) { if (x & mask) putchar ('1'); else putchar ('0'); 'выглядит как печать двоичного значения, что имеет мало общего с« Я должен XOR 4 8-битные части целых чисел ». Прошу прояснить вашу цель или проблему, – chux

ответ

0

аккумулировать XOR из 8-битных значений, вы просто смещаются и XOR каждую часть Значение. Концептуально это:

uint32_t checksum = ((a >> 24)^(a >> 16)^(a >> 8)^a) & 0xff; 

Однако, так как XOR может быть сделано в любом порядке, вы можете сделать то же самое с меньшим количеством операций:

uint32_t checksum = (a >> 16)^a; 
checksum = ((checksum >> 8)^checksum) & 0xff; 

Если вы делаете это в течение многих значений, вы можете расширяйте эту идею, только уменьшая значение в самом конце. Это очень похоже на то, как параллельно коммутативной операции выполняются в больших регистров с использованием технологий, таких как SIMD (и в самом деле, компиляторы с поддержкой SIMD должны быть в состоянии оптимизировать следующий код, чтобы сделать его гораздо быстрее):

uint32_t simple_checksum(uint32_t *v, size_t count) 
{ 
    uint32_t checksum = 0; 
    uint32_t *end = v + count; 
    for(; v != end; v++) 
    { 
     checksum ^= *v;   /* accumulate XOR of each 32-bit value  */ 
    } 
    checksum ^= (checksum >> 16); /* XOR high and low words into low word */ 
    checksum ^= (checksum >> 8); /* XOR each byte of low word into low byte */ 
    return checksum & 0xff;  /* everything from bits 8-31 is rubbish */ 
} 
+0

О, отлично, это было то, что я пытался сделать, спасибо за помощь! – Jasmine

+1

'a = ((a >> 16)^a); checksum = ((a >> 8)^a) & 0xFF; 'потребует меньше сдвигов –

+0

Это хорошая точка @ LưuVĩnhPhúc. Я соответствующим образом перефразировал ответ. – paddy