Archive for the ‘codice’ tag
Le piccole cose
Che poi se io fossi un poliziotto, un carabiniere, ma anche un semplice vigile urbano, il mio massimo divertimento sarebbe fermare tutti i motociclisti e multare quel buon novanta percento che ha la targa inclinata per evitare gli autovelox.
Poi uno dice che perde fiducia nelle istituzioni, la certezza della pena e quelle cose lì.
Dio è nei dettagli.
La superiorità dell’uomo sulla macchina
Oggi mi sono trovato a dover risolvere un problema che evidenzia bene come la macchina uomo sia infinitamente superiore ad un computer: ribaltare una stringa arbitraria di bit.
Mi spiego con un esempio, per chi non abbia confidenza con l’informatica di base: il problemae è partire da una fila di di bit tipo 0000000000000001 ed ottenere questa: 1000000000000000.
Già ad occhio si vede come il problema sembri una stupidaggine, anche mia nipotina di 5 anni riuscirebbe a farlo se qualcuno fosse in grado di farla interessare ad una cosa così noiosa.
Ma scrivere un programma in C che lo faccia e non sia troppo stupido non è una cosa così semplice. Almeno per me non lo è stato.
Quando dico non troppo stupido intendo dire che quello che volevo era un pezzo di codice che fosse il più generico possibile o meglio, il meno specifico possibile.
Perché scrivere del codice che ribalti un byte, otto bit, non è molto difficile, anzi. C’è anche fior di letteratura su google al riguardo. E così per una word, sedici bit, o un long, trentadue bit.
Il difficile è fare una stessa funzione che accetti un qualsiasi numero di byte e li ribalti.
Dopo un po’ di pensamenti e ripensamenti, sono giunto ad una soluzione che trovo elegante, la annoto qui per ricordarmela, farla eventualmente trovare e accettare miglioramenti e critiche se qualcuno ne avesse.
L’algoritmo è completamente diverso da quello che userebbe una mente umana, perlomeno una sana; il ribaltamento è fatto in due passi: per prima cosa si prendono i singoli byte del vettore e li si scambia di posto in modo che si leggano dal fondo verso l’inizio. Chiamando tre byte B1, B2 e B3 si passa quindi da una situazione di partenza in cui si ha:
B1B2B3
ad una in cui si ottiene:
B3B2B1
A questo punto si invertono i singoli bit che compongono ogni byte, passando da:
b7b6b5b4b3b2b1b0
a:
b0b1b2b3b4b5b6b7
Semplice, no?
Di seguito il codice per farlo.
(Non l’ho compilato, è da prendere com’è, non usatelo per mandare una navicella nello spazio senza prima testarlo a fondo…)
—SNIP—
// How to mirror an undefined number of bits
void main(void);
void ReverseArray(u8 *, u8);
void SwapBytes(u8 *, u8 *);
u8 ByteReverse(u8);
// A three elements array for testing purpose, but it works with an arbitrary number of bytes
u8 Array[3] =
{
00000000b
00000000b
00000001b
};
void main(void)
{
ReverseArray(Array);
}
void ReverseArray(u8 *variable_ptr, u8 variable_size)
{
u8 i;
u8 j;
i = 0;
j = variable_size - 1;
while (i < j)
{
SwapBytes(variable_ptr + i, variable_ptr + j);
i++;
j--;
}
for (i = 0; i < variable_size; i++)
{
*(variable_ptr + i) = ByteReverse(*(variable_ptr + i));
}
}
void SwapBytes(u8 *first_byte_ptr, u8 *second_byte_ptr)
{
u8 temp_byte;
temp_byte = *first_byte_ptr;
*first_byte_ptr = *second_byte_ptr;
*second_byte_ptr = temp_byte;
}
u8 ByteReverse(u8 byte_variable)
{
u8 i;
u8 reversed_variable;
reversed_variable = 0;
for (i = 0; i < SIZE_BYTE; i++)
{
if (byte_variable & (1 << i))
{
reversed_variable |= 1 << ((SIZE_BYTE - 1) - i);
}
}
return reversed_variable;
}
—PINS—