none of the above

unnecessary words from my inside

Archive for the ‘codice’ tag

Le piccole cose

without comments

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.

Written by effemmeffe

August 4th, 2009 at 2:56 pm

La superiorità dell’uomo sulla macchina

with 6 comments

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—

Written by effemmeffe

May 14th, 2008 at 5:34 pm