1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
| #include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define MAT_GEN 0x0DB87421u /* Matrice generatrice de Hamming */
#define MAT_GEN_MASK 0xF0000000u /* Masque de la matrice generatrice */
/* XXX Warning: macro uses nb_cols */
#define G_EXTRACT_BIT(X, COLUMN) ((X >> (nb_cols - COLUMN - 1)) & 1)
void debug_print_binary(unsigned long long value, unsigned short nb_digits, unsigned short pack_size, char* begin_str) {
if (nb_digits > 0) {
unsigned long long mask;
unsigned short digit, display_count, tmp;
mask = (((unsigned long long) 1) << (nb_digits - 1));
printf("%s0x%llX (", begin_str, value);
if (pack_size == 0) { pack_size = 8; }
tmp = (nb_digits % pack_size);
display_count = 0;
/* Left padding with zeros */
if (tmp != 0) {
tmp = (pack_size - tmp);
for(digit=0; digit < tmp; ++digit, ++display_count) { printf("0"); }
}
/* Display first digit to avoid space in somes cases - (nb_digits % pack_size) == 0 */
printf("%u", ((value & mask)? 1: 0));
for(digit=1, ++display_count, mask /= 2; digit < nb_digits; ++digit, mask /= 2 /*or mask >>= 1*/, ++display_count) {
if ((display_count % pack_size) != 0) {
printf("%u", ((value & mask)? 1: 0));
} else {
printf(" %u", ((value & mask)? 1: 0));
}
}
printf(")\n");
}
}
unsigned int get_nb_bits(unsigned int value) {
return ((value > 0)? (log2(value) + 1): 0);
}
unsigned int hamm_product_mat(unsigned int matrix,
unsigned int data,
unsigned int nb_lines,
unsigned int nb_cols,
unsigned int matrix_mask) {
unsigned int line, column, value, final_value, line_val, col_mask;
final_value = 0;
for(line=0; line < nb_lines; ++line) {
line_val = ((matrix & ~matrix_mask) >> ((nb_lines - line - 1) * 4)) & 0xF;
col_mask = (1 << (nb_cols - 1));
value = (G_EXTRACT_BIT(line_val, 0) & G_EXTRACT_BIT(data, 0));
printf("Next line (hex): %X\n(%u & %u)", line_val, G_EXTRACT_BIT(line_val, 0), G_EXTRACT_BIT(data, 0));
for(column=1; column < nb_cols; ++column) {
col_mask >>= 1; /* or col_mask /= 2 */
value ^= (G_EXTRACT_BIT(line_val, column) & G_EXTRACT_BIT(data, column));
printf(" ^ (%u & %u)", G_EXTRACT_BIT(line_val, column), G_EXTRACT_BIT(data, column));
}
final_value |= ((value & 1) << (nb_lines - line - 1));
printf(" = %u\n\n", value);
}
return final_value;
}
int main()
{
unsigned int data = 13;
switch( get_nb_bits(data) ) {
case 1: case 2: case 3: case 4:
{
unsigned int result, nb_digits;
result = hamm_product_mat(MAT_GEN, data, 8, 4, MAT_GEN_MASK);
nb_digits = get_nb_bits(result);
nb_digits = ((((nb_digits - 1) / 8) + 1) * 8); /* Next multiple of 8 */
debug_print_binary(result, nb_digits, 8, "Result: ");
}
break;
case 0:
printf("XXX - error: data == 0\n");
break;
default:
printf("XXX - error (0xFFFFFFFF): data width > 4\n");
}
return EXIT_SUCCESS;
} |
Partager